From 8ed0a5228ce0b8b77610256ff788f63540e8aa94 Mon Sep 17 00:00:00 2001 From: Harvey Zhao Date: Fri, 11 Sep 2026 21:06:33 +0800 Subject: [PATCH] refactor(core): [CORE-23] complete keyboard controls and focus lifecycle --- docs/assets/ts/artplayer.d.ts | 5 + docs/compiled/artplayer.js | 2 +- docs/compiled/artplayer.legacy.js | 2 +- docs/compiled/artplayer.mjs | 1515 +- docs/compiled/i18n/ar.js | 2 +- docs/compiled/i18n/ar.mjs | 5 + docs/compiled/i18n/cs.js | 2 +- docs/compiled/i18n/cs.mjs | 13 +- docs/compiled/i18n/es.js | 2 +- docs/compiled/i18n/es.mjs | 5 + docs/compiled/i18n/fa.js | 2 +- docs/compiled/i18n/fa.mjs | 13 +- docs/compiled/i18n/fr.js | 2 +- docs/compiled/i18n/fr.mjs | 13 +- docs/compiled/i18n/id.js | 2 +- docs/compiled/i18n/id.mjs | 5 + docs/compiled/i18n/pl.js | 2 +- docs/compiled/i18n/pl.mjs | 5 + docs/compiled/i18n/ru.js | 2 +- docs/compiled/i18n/ru.mjs | 5 + docs/compiled/i18n/tr.js | 2 +- docs/compiled/i18n/tr.mjs | 11 +- docs/compiled/i18n/vi.js | 2 +- docs/compiled/i18n/vi.mjs | 5 + docs/compiled/i18n/zh-tw.js | 2 +- docs/compiled/i18n/zh-tw.mjs | 13 +- package.json | 2 +- packages/artplayer/ARCHITECTURE.md | 225 + packages/artplayer/dist/artplayer.cts | 29 + packages/artplayer/dist/artplayer.js | 2 +- packages/artplayer/dist/artplayer.legacy.js | 2 +- packages/artplayer/dist/artplayer.mjs | 1515 +- packages/artplayer/dist/artplayer.mts | 2 + packages/artplayer/dist/artplayer.ts | 216 + packages/artplayer/dist/component.ts | 143 + packages/artplayer/dist/config.ts | 81 + packages/artplayer/dist/cssVar.ts | 45 + packages/artplayer/dist/emitter.ts | 8 + packages/artplayer/dist/events.ts | 106 + packages/artplayer/dist/i18n.ts | 61 + packages/artplayer/dist/i18n/ar.js | 2 +- packages/artplayer/dist/i18n/ar.mjs | 5 + packages/artplayer/dist/i18n/cs.js | 2 +- packages/artplayer/dist/i18n/cs.mjs | 13 +- packages/artplayer/dist/i18n/es.js | 2 +- packages/artplayer/dist/i18n/es.mjs | 5 + packages/artplayer/dist/i18n/fa.js | 2 +- packages/artplayer/dist/i18n/fa.mjs | 13 +- packages/artplayer/dist/i18n/fr.js | 2 +- packages/artplayer/dist/i18n/fr.mjs | 13 +- packages/artplayer/dist/i18n/id.js | 2 +- packages/artplayer/dist/i18n/id.mjs | 5 + packages/artplayer/dist/i18n/pl.js | 2 +- packages/artplayer/dist/i18n/pl.mjs | 5 + packages/artplayer/dist/i18n/ru.js | 2 +- packages/artplayer/dist/i18n/ru.mjs | 5 + packages/artplayer/dist/i18n/tr.js | 2 +- packages/artplayer/dist/i18n/tr.mjs | 11 +- packages/artplayer/dist/i18n/vi.js | 2 +- packages/artplayer/dist/i18n/vi.mjs | 5 + packages/artplayer/dist/i18n/zh-tw.js | 2 +- packages/artplayer/dist/i18n/zh-tw.mjs | 13 +- packages/artplayer/dist/icons.ts | 30 + packages/artplayer/dist/language.cts | 5 + packages/artplayer/dist/language.mts | 1 + packages/artplayer/dist/legacy/language.ts | 4 + packages/artplayer/dist/option.ts | 331 + packages/artplayer/dist/playback.ts | 6 + packages/artplayer/dist/player.ts | 113 + packages/artplayer/dist/plugin.ts | 10 + packages/artplayer/dist/quality.ts | 16 + packages/artplayer/dist/runtime.cts | 54 + packages/artplayer/dist/runtime.mts | 2 + packages/artplayer/dist/runtime.ts | 125 + packages/artplayer/dist/runtime/component.ts | 65 + .../artplayer/dist/runtime/construction.ts | 19 + packages/artplayer/dist/runtime/events.ts | 26 + packages/artplayer/dist/runtime/media.ts | 41 + packages/artplayer/dist/runtime/option.ts | 28 + packages/artplayer/dist/runtime/player.ts | 78 + packages/artplayer/dist/runtime/plugin.ts | 13 + packages/artplayer/dist/runtime/services.ts | 57 + packages/artplayer/dist/runtime/setting.ts | 58 + packages/artplayer/dist/runtime/subtitle.ts | 38 + packages/artplayer/dist/runtime/template.ts | 42 + packages/artplayer/dist/runtime/utils.ts | 67 + packages/artplayer/dist/setting.ts | 95 + packages/artplayer/dist/subtitle.ts | 36 + packages/artplayer/dist/template.ts | 27 + packages/artplayer/dist/utils.ts | 73 + packages/artplayer/public/i18n.ts | 5 + .../artplayer/src/accessibility/button.ts | 48 + packages/artplayer/src/accessibility/focus.ts | 50 + .../artplayer/src/accessibility/keyboard.ts | 14 + .../src/accessibility/moved-focus.ts | 9 + .../src/accessibility/overlay-focus.ts | 26 + .../src/accessibility/player-focus.ts | 22 + .../artplayer/src/accessibility/slider.ts | 55 + .../src/accessibility/suspend-focus.ts | 57 + packages/artplayer/src/component/focus.ts | 50 + .../artplayer/src/contextmenu/aspectRatio.ts | 6 +- packages/artplayer/src/contextmenu/choices.ts | 20 + packages/artplayer/src/contextmenu/flip.ts | 6 +- packages/artplayer/src/contextmenu/index.ts | 43 +- .../artplayer/src/contextmenu/keyboard.ts | 144 + .../artplayer/src/contextmenu/playbackRate.ts | 6 +- .../artplayer/src/contextmenu/position.ts | 17 + packages/artplayer/src/control/airplay.ts | 3 + packages/artplayer/src/control/fullscreen.ts | 3 + .../artplayer/src/control/fullscreenWeb.ts | 3 + packages/artplayer/src/control/index.ts | 20 +- packages/artplayer/src/control/pip.ts | 3 + .../artplayer/src/control/playAndPause.ts | 5 + packages/artplayer/src/control/progress.ts | 2 + .../src/control/progress/keyboard.ts | 77 + packages/artplayer/src/control/screenshot.ts | 3 + .../src/control/selector-keyboard.ts | 191 + packages/artplayer/src/control/selector.ts | 14 +- packages/artplayer/src/control/setting.ts | 5 + packages/artplayer/src/control/types.ts | 9 +- packages/artplayer/src/control/volume.ts | 34 +- packages/artplayer/src/display/mini-focus.ts | 36 + packages/artplayer/src/display/mini-view.ts | 28 +- packages/artplayer/src/display/mini.ts | 10 +- packages/artplayer/src/display/types.ts | 1 + .../artplayer/src/display/web-fullscreen.ts | 12 +- packages/artplayer/src/i18n/ar.ts | 5 + packages/artplayer/src/i18n/cs.ts | 5 + packages/artplayer/src/i18n/es.ts | 5 + packages/artplayer/src/i18n/fa.ts | 5 + packages/artplayer/src/i18n/fr.ts | 5 + packages/artplayer/src/i18n/id.ts | 5 + packages/artplayer/src/i18n/pl.ts | 5 + packages/artplayer/src/i18n/ru.ts | 5 + packages/artplayer/src/i18n/tr.ts | 5 + packages/artplayer/src/i18n/vi.ts | 5 + packages/artplayer/src/i18n/zh-cn.ts | 5 + packages/artplayer/src/i18n/zh-tw.ts | 5 + packages/artplayer/src/info/keyboard.ts | 66 + packages/artplayer/src/info/poll.ts | 7 +- .../artplayer/src/input/keyboard-focus.ts | 11 +- .../artplayer/src/plugins/lock-keyboard.ts | 44 + packages/artplayer/src/plugins/lock.ts | 18 +- packages/artplayer/src/setting/index.ts | 5 + .../artplayer/src/setting/keyboard-focus.ts | 55 + .../artplayer/src/setting/keyboard-item.ts | 30 + packages/artplayer/src/setting/keyboard.ts | 134 + packages/artplayer/src/setting/render.ts | 16 + packages/artplayer/src/setting/selection.ts | 2 + packages/artplayer/src/setting/types.ts | 1 + packages/artplayer/src/setting/update.ts | 4 + .../artplayer/src/source/restore-position.ts | 6 +- .../artplayer/src/style/accessibility.less | 22 + packages/artplayer/src/style/index.less | 1 + packages/artplayer/src/style/mini.less | 8 +- packages/artplayer/src/style/plugins.less | 14 + packages/artplayer/src/style/selector.less | 7 +- packages/artplayer/src/style/volume.less | 7 +- packages/artplayer/src/utils/component.ts | 25 +- packages/artplayer/types/i18n.d.ts | 5 + .../baselines/keyboard-buttons-partial.json | 812 + .../keyboard-contextmenu-partial.json | 2757 ++ .../keyboard-control-focus-partial.json | 2959 ++ .../baselines/keyboard-info-lock-partial.json | 2121 ++ refactor/baselines/keyboard-mini-partial.json | 1893 ++ .../baselines/keyboard-selectors-partial.json | 2066 ++ .../baselines/keyboard-settings-partial.json | 3320 ++ .../baselines/keyboard-sliders-partial.json | 1128 + refactor/baselines/keyboard-validation.json | 27586 ++++++++++++++++ .../2026-09-11-CORE-23-keyboard-focus.md | 173 + refactor/plan.md | 5 +- refactor/progress.md | 74 + refactor/risk-table.md | 2 +- refactor/risks.json | 12 +- refactor/tasks.json | 7 +- test/accessibility-button.test.js | 129 + test/accessibility-focus.test.js | 110 + test/accessibility-slider.test.js | 237 + .../browser/accessibility-contextmenu.spec.js | 278 + test/browser/accessibility-controls.spec.js | 168 + test/browser/accessibility-info.spec.js | 136 + .../browser/accessibility-integration.spec.js | 130 + test/browser/accessibility-lock.spec.js | 127 + test/browser/accessibility-mini.spec.js | 142 + test/browser/accessibility-selector.spec.js | 252 + test/browser/accessibility-setting.spec.js | 269 + test/browser/accessibility-slider.spec.js | 155 + test/browser/accessibility.spec.js | 161 + test/builtin-layers.test.js | 13 +- test/prompt-components.test.js | 12 +- 190 files changed, 53981 insertions(+), 489 deletions(-) create mode 100644 packages/artplayer/dist/artplayer.cts create mode 100644 packages/artplayer/dist/artplayer.mts create mode 100644 packages/artplayer/dist/artplayer.ts create mode 100644 packages/artplayer/dist/component.ts create mode 100644 packages/artplayer/dist/config.ts create mode 100644 packages/artplayer/dist/cssVar.ts create mode 100644 packages/artplayer/dist/emitter.ts create mode 100644 packages/artplayer/dist/events.ts create mode 100644 packages/artplayer/dist/i18n.ts create mode 100644 packages/artplayer/dist/icons.ts create mode 100644 packages/artplayer/dist/language.cts create mode 100644 packages/artplayer/dist/language.mts create mode 100644 packages/artplayer/dist/legacy/language.ts create mode 100644 packages/artplayer/dist/option.ts create mode 100644 packages/artplayer/dist/playback.ts create mode 100644 packages/artplayer/dist/player.ts create mode 100644 packages/artplayer/dist/plugin.ts create mode 100644 packages/artplayer/dist/quality.ts create mode 100644 packages/artplayer/dist/runtime.cts create mode 100644 packages/artplayer/dist/runtime.mts create mode 100644 packages/artplayer/dist/runtime.ts create mode 100644 packages/artplayer/dist/runtime/component.ts create mode 100644 packages/artplayer/dist/runtime/construction.ts create mode 100644 packages/artplayer/dist/runtime/events.ts create mode 100644 packages/artplayer/dist/runtime/media.ts create mode 100644 packages/artplayer/dist/runtime/option.ts create mode 100644 packages/artplayer/dist/runtime/player.ts create mode 100644 packages/artplayer/dist/runtime/plugin.ts create mode 100644 packages/artplayer/dist/runtime/services.ts create mode 100644 packages/artplayer/dist/runtime/setting.ts create mode 100644 packages/artplayer/dist/runtime/subtitle.ts create mode 100644 packages/artplayer/dist/runtime/template.ts create mode 100644 packages/artplayer/dist/runtime/utils.ts create mode 100644 packages/artplayer/dist/setting.ts create mode 100644 packages/artplayer/dist/subtitle.ts create mode 100644 packages/artplayer/dist/template.ts create mode 100644 packages/artplayer/dist/utils.ts create mode 100644 packages/artplayer/src/accessibility/button.ts create mode 100644 packages/artplayer/src/accessibility/focus.ts create mode 100644 packages/artplayer/src/accessibility/keyboard.ts create mode 100644 packages/artplayer/src/accessibility/moved-focus.ts create mode 100644 packages/artplayer/src/accessibility/overlay-focus.ts create mode 100644 packages/artplayer/src/accessibility/player-focus.ts create mode 100644 packages/artplayer/src/accessibility/slider.ts create mode 100644 packages/artplayer/src/accessibility/suspend-focus.ts create mode 100644 packages/artplayer/src/component/focus.ts create mode 100644 packages/artplayer/src/contextmenu/choices.ts create mode 100644 packages/artplayer/src/contextmenu/keyboard.ts create mode 100644 packages/artplayer/src/contextmenu/position.ts create mode 100644 packages/artplayer/src/control/progress/keyboard.ts create mode 100644 packages/artplayer/src/control/selector-keyboard.ts create mode 100644 packages/artplayer/src/display/mini-focus.ts create mode 100644 packages/artplayer/src/info/keyboard.ts create mode 100644 packages/artplayer/src/plugins/lock-keyboard.ts create mode 100644 packages/artplayer/src/setting/keyboard-focus.ts create mode 100644 packages/artplayer/src/setting/keyboard-item.ts create mode 100644 packages/artplayer/src/setting/keyboard.ts create mode 100644 packages/artplayer/src/style/accessibility.less create mode 100644 refactor/baselines/keyboard-buttons-partial.json create mode 100644 refactor/baselines/keyboard-contextmenu-partial.json create mode 100644 refactor/baselines/keyboard-control-focus-partial.json create mode 100644 refactor/baselines/keyboard-info-lock-partial.json create mode 100644 refactor/baselines/keyboard-mini-partial.json create mode 100644 refactor/baselines/keyboard-selectors-partial.json create mode 100644 refactor/baselines/keyboard-settings-partial.json create mode 100644 refactor/baselines/keyboard-sliders-partial.json create mode 100644 refactor/baselines/keyboard-validation.json create mode 100644 refactor/changes/2026-09-11-CORE-23-keyboard-focus.md create mode 100644 test/accessibility-button.test.js create mode 100644 test/accessibility-focus.test.js create mode 100644 test/accessibility-slider.test.js create mode 100644 test/browser/accessibility-contextmenu.spec.js create mode 100644 test/browser/accessibility-controls.spec.js create mode 100644 test/browser/accessibility-info.spec.js create mode 100644 test/browser/accessibility-integration.spec.js create mode 100644 test/browser/accessibility-lock.spec.js create mode 100644 test/browser/accessibility-mini.spec.js create mode 100644 test/browser/accessibility-selector.spec.js create mode 100644 test/browser/accessibility-setting.spec.js create mode 100644 test/browser/accessibility-slider.spec.js create mode 100644 test/browser/accessibility.spec.js diff --git a/docs/assets/ts/artplayer.d.ts b/docs/assets/ts/artplayer.d.ts index 9c953fedf..f32f9af99 100644 --- a/docs/assets/ts/artplayer.d.ts +++ b/docs/assets/ts/artplayer.d.ts @@ -275,10 +275,15 @@ declare namespace ArtplayerDefinitions { } export type I18nKeys = 'en' | 'zh-cn' | 'zh-tw' | 'pl' | 'cs' | 'es' | 'fa' | 'fr' | 'id' | 'ru' | 'tr' | 'ar' | 'vi' | (string & Record) export interface I18nValue { + 'Context Menu'?: string + 'Lock'?: string 'Video Info': string 'Close': string 'Video Load Failed': string 'Volume': string + 'Progress'?: string + 'Back'?: string + 'Settings'?: string 'Play': string 'Pause': string 'Rate': string diff --git a/docs/compiled/artplayer.js b/docs/compiled/artplayer.js index bd3ed2efa..a433c0626 100644 --- a/docs/compiled/artplayer.js +++ b/docs/compiled/artplayer.js @@ -67,4 +67,4 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),l=/^(?:(?!chrome|android).)*safari/i.test(s),c=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=c||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,p=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,u="undefined"!==typeof window&&"undefined"!==typeof document;const h={properties:["audioTracks","autoplay","buffered","controller","controls","crossOrigin","currentSrc","currentTime","defaultMuted","defaultPlaybackRate","duration","ended","error","loop","mediaGroup","muted","networkState","paused","playbackRate","played","preload","readyState","seekable","seeking","src","startDate","textTracks","videoTracks","volume"],methods:["addTextTrack","canPlayType","load","play","pause"],events:["abort","canplay","canplaythrough","durationchange","emptied","ended","error","loadeddata","loadedmetadata","loadstart","pause","play","playing","progress","ratechange","seeked","seeking","stalled","suspend","timeupdate","volumechange","waiting"],prototypes:["width","height","videoWidth","videoHeight","poster","webkitDecodedFrameCount","webkitDroppedFrameCount","playsInline","webkitSupportsFullscreen","webkitDisplayingFullscreen","onenterpictureinpicture","onleavepictureinpicture","disablePictureInPicture","cancelVideoFrameCallback","requestVideoFrameCallback","getVideoPlaybackQuality","requestPictureInPicture","webkitEnterFullScreen","webkitEnterFullscreen","webkitExitFullScreen","webkitExitFullscreen"]};class f extends Error{constructor(t){super("Failed to release ArtPlayer resources"),this.errors=t,this.name="ResourceCleanupError"}}class m{constructor(){this.cleanups=new Set,this.disposed=!1}get closed(){return this.disposed}add(t){let e=!0;const r=()=>{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new m,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof f?t.push(...e.errors):t.push(e)}if(t.length)throw new f(t)}}const g=new WeakMap,v=new WeakMap;function y(t){const e=g.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function b(t){return y(t).scope}function w(t){const e=y(t);return e.destroying||e.scope.closed}function x(t,e,r,n,o=!1){const i=y(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],s=t=>{try{t()}catch(e){a.push(...e instanceof f?e.errors:[e])}};n&&t.template?.$video&&s(()=>t.reset()),s(()=>i.scope.dispose()),s(()=>(t.template||i.mountingTemplate)?.destroy(r));const l=e.indexOf(t);-1!==l&&e.splice(l,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),s(()=>t.emit("destroy")),s(()=>i.finalizers.dispose()),o&&i.rollback&&s(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const c of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",c);if(a.length)throw a[0]}const k=new WeakMap;function $(t,e){const r=b(t).child();return k.set(e,r),r}function E(t){const e=k.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function T(t){k.get(t)?.dispose()}function C(t,e,r,n){const o=E(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function L(t,e){return{on:(r,n)=>{C(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=E(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}function S(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode??null;return"undefined"===typeof window||e.includes(window)||e.push(window),e}function P(t,e){return S(t).includes(e)}function M(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function z(t){return t.getBoundingClientRect()}function A(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;";try{document.body.appendChild(t);const e=getComputedStyle(t);return{top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0}}finally{t.remove()}}function R(t,e=document){return e.querySelector(t)}function O(t,e){return t.classList.add(e)}function I(t,e){return t.classList.remove(e)}function N(t,e){return t.classList.contains(e)}function _(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function W(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function D(t,e){W(t).forEach(t=>I(t,e)),O(t,e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function V(t){return document.createElement(t)}function Y(t,e,r="top"){p||(t.setAttribute("aria-label",e),O(t,"hint--rounded"),O(t,`hint--${r}`))}function B(t="",e=""){const r=V("i");return O(r,"art-icon"),O(r,`art-icon-${t}`),_(r,e),r}function H(t,e,r){return t.style[e]=r,t}function j(t,e){for(const r in e)H(t,r,e[r]);return t}function q(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new m;let a=!1,s=()=>{};function l(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function c(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void c(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;d(l,()=>c(l)),i.closed||(l.src=e)}catch(e){l(e)}}))}),i.closed||(n.src=t)}catch(p){l(p)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(p){l(p)}},e.onerror=()=>l(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}class U extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function X(t,e){if(!t)throw new U(e);return t}function G(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function K(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function Z(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function J(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function Q(t){return t.charAt(0).toUpperCase()+t.slice(1)}function tt(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const et={"&":"&","<":"<",">":">","'":"'",'"':"""},rt={"&":"&","<":"<",">":">","'":"'",""":'"'},nt=/(&|<|>|'|")/g;function ot(t){return t.replace(/[&<>'"]/g,t=>et[t]||t)}const it=Object.defineProperty,{hasOwnProperty:at}=Object.prototype;function st(t,e){return at.call(t,e)}function lt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function ct(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?ct(o,i):i,it(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function dt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function pt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function ut(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const ht=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:U,addClass:O,append:_,assToVtt:ut,capitalize:Q,clamp:J,createElement:V,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:it,download:Z,errorHandle:X,escape:ot,get:lt,getComposedPath:S,getExt:K,getIcon:B,getRect:z,getSafeAreaInsets:A,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:N,includeFromEvent:P,inverseClass:D,isBrowser:u,isIOS:c,isIOS13:d,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:p,isSafari:l,loadImg:function(t,e){return q(t,e,void 0)},mergeDeep:ct,query:R,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:I,replaceElement:F,secondToTime:tt,setStyle:H,setStyleText:a,setStyles:j,siblings:W,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:M,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:Y,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:s,vttToBlob:pt},Symbol.toStringTag,{value:"Module"}));function ft(t,e){return _(t,e)}function mt(t,e){return e.querySelector(t)}const gt="array",vt="boolean",yt="string",bt="number",wt="object",xt="function";function kt(t,e,r){return X(e===yt||e===bt||t instanceof Element,`${r.join(".")} require '${yt}' or 'Element' type`)}const $t={html:kt,disable:`?${vt}`,name:`?${yt}`,index:`?${bt}`,style:`?${wt}`,click:`?${xt}`,mounted:`?${xt}`,tooltip:`?${yt}|${bt}`,width:`?${bt}`,selector:`?${gt}`,onSelect:`?${xt}`,switch:`?${vt}`,onSwitch:`?${xt}`,range:`?${gt}`,onRange:`?${xt}`,onChange:`?${xt}`},Et={id:yt,container:kt,url:yt,poster:yt,type:yt,theme:yt,lang:yt,volume:bt,isLive:vt,muted:vt,autoplay:vt,autoSize:vt,autoMini:vt,loop:vt,flip:vt,playbackRate:vt,aspectRatio:vt,screenshot:vt,setting:vt,hotkey:vt,pip:vt,mutex:vt,backdrop:vt,fullscreen:vt,fullscreenWeb:vt,subtitleOffset:vt,miniProgressBar:vt,useSSR:vt,playsInline:vt,lock:vt,gesture:vt,fastForward:vt,autoPlayback:vt,autoOrientation:vt,airplay:vt,proxy:`?${xt}`,plugins:[xt],layers:[$t],contextmenu:[$t],settings:[$t],controls:[{...$t,position:(t,e,r)=>{const n=["top","left","right"];return X("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${vt}`,html:yt,url:yt}],highlight:[{time:bt,text:yt}],thumbnails:{url:yt,number:bt,column:bt,width:bt,height:bt,scale:bt},subtitle:{url:yt,name:yt,type:yt,style:wt,escape:vt,encoding:yt,onVttLoad:xt},moreVideoAttr:wt,i18n:wt,icons:wt,cssVar:wt,customType:wt},Tt=new WeakSet;class Ct{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return N(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?O(e,r):I(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(w(this.art))return;const e="function"===typeof t?t(this.art):t;if(w(this.art))return;if(e.html=e.html||"",o(e,$t),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;X(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=$(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,r);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){O(t,`art-${r}`),O(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):_(e,t),i.html&&_(t,i.html),i.style&&j(t,i.style),i.tooltip&&Y(t,i.tooltip)}(i,this.$parent,this.name,r,this.id,e),a.closed)return;if(e.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,r,i),c=!0,n.set(r,{$ref:i,events:s,option:e}),e.mounted&&e.mounted.call(this.art,i),i}catch(d){try{T(i)}catch(p){console.warn("ArtPlayer component cleanup failed:",p)}throw n.get(r)?.$ref===i&&n.delete(r),c&&this[r]===i&&(l?Object.defineProperty(this,r,l):delete this[r]),i.remove(),d}}remove(t){X(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Tt.has(e)){Tt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{T(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Tt.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Lt extends Ct{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,$(t,this.$parent),p||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=L(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return{...t,html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=L(e,t),n=R('[data-value="1"]',t);n&&D(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&D(r,"art-current")})}}}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return{...t,html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=L(e,t),n=R('[data-value="default"]',t);n&&D(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&D(r,"art-current")})}}}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(Q(t))}`).join("");return{...t,html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=L(e,t),n=R('[data-value="normal"]',t);n&&D(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&D(r,"art-current")})}}}}({name:"flip",index:30})),this.add(function(t){return e=>({...t,html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return{...t,html:`ArtPlayer ${i}`}}({name:"version",index:50})),this.add(function(t){return e=>({...t,html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=z(e),{height:c,width:d}=z(r);let p=n-s,u=o-l;n+d>s+a&&(p=a-d),o+c>l+i&&(u=i-c),j(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{P(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function St(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{s?.removeEventListener("abort",l)}}),s?.addEventListener("abort",l,{once:!0}),l}function Pt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Mt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const zt=new WeakMap,At=new WeakMap,Rt=new WeakMap;function Ot(t){return Rt.get(t)||b(t)}function It(t){const e=zt.get(t),r=Rt.get(t);return()=>zt.get(t)===e&&(!e||e.active())&&Rt.get(t)===r&&(!r||!r.closed)}function Nt(t){const e=Rt.get(t),r=b(t).child(),n=r.child();Rt.set(t,r),r.add(()=>{Rt.get(t)===r&&Rt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!w(t)&&!n.closed&&zt.get(t)===o};return zt.set(t,o),n.add(()=>{zt.get(t)===o&&zt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function _t(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function Wt(t,e,r){At.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{At.get(t)===e&&(At.delete(t),_t(e))}}function Dt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Ft(t,e){const{$progress:r}=t.template,{left:n}=z(r),o=J((p?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:tt(i),width:o,percentage:J(o/r.clientWidth,0,1)}}function Vt(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Ft(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Yt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=E(e),{on:a}=L(t,e);let s=()=>{};const l=mt(".art-progress-hover",e),c=mt(".art-progress-loaded",e),d=mt(".art-progress-played",e),u=mt(".art-progress-highlight",e),h=mt(".art-progress-indicator",e),f=mt(".art-progress-tip",e);function m(r,n){const{width:o,time:i}=n||Ft(t,r);f.textContent=i||"00:00";const a=f.clientWidth;o<=a/2?H(f,"left",0):o>e.clientWidth-a/2?H(f,"left",e.clientWidth-a+"px"):H(f,"left",o-a/2+"px")}r.indicator?_(h,r.indicator):H(h,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const g="played"===r&&a&&p;if("loaded"===r&&H(c,"width",100*n+"%"),"hover"===r&&(H(l,"width",100*n+"%"),P(a,u)?function(r){const{width:n}=Ft(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;f.textContent=o??"";const i=f.clientWidth;n<=i/2?H(f,"left",0):n>e.clientWidth-i/2?H(f,"left",e.clientWidth-i+"px"):H(f,"left",n-i/2+"px")}(a):m(a),0===n?I(o,"art-progress-hover"):O(o,"art-progress-hover")),"played"===r&&(H(d,"width",100*n+"%"),H(h,"left",100*n+"%")),g){O(o,"art-progress-hover");m(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=Pt(i,()=>{I(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function Bt(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Yt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=L(t,e),a=E(e);let s=0;const l=()=>{const e=It(t);return()=>!a.closed&&!w(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!p){let e;i(r,"click",e=>{e.target!==n&&Vt(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=Ft(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(n?.()){const{second:o,percentage:i}=Ft(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t)}})}function Ht(t){const{option:e}=t.art;e.isLive||t.add(Bt({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e,a=ft(t,o.play),s=ft(t,o.pause);function l(){H(a,"display","flex"),H(s,"display","none")}function c(){H(a,"display","none"),H(s,"display","flex")}Y(a,i.get("Play")),Y(s,i.get("Pause")),n(a,"click",()=>{G(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o}=e,i=ft(t,o.volume),a=ft(t,o.volumeClose),s=ft(t,'
'),l=ft(s,'
'),c=ft(l,'
'),d=ft(l,'
'),u=ft(d,'
'),h=ft(u,'
'),f=ft(d,'
');function m(t){const{top:e,height:r}=z(d);return 1-(t.clientY-e)/r}function g(){if(e.muted||0===e.volume)H(i,"display","none"),H(a,"display","flex"),H(f,"top","100%"),H(h,"top","100%"),c.textContent="0";else{const t=100*e.volume;H(i,"display","flex"),H(a,"display","none"),H(f,"top",100-t+"%"),H(h,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(g(),r("video:volumechange",g),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),p)H(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=m(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=m(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>({...t,style:p?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=L(e,t);function n(){const r=`${tt(e.currentTime)} / ${tt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!b(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!p&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=L(e,t),{icons:n}=e;ft(t,n.screenshot),r(t,"click",()=>{G(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e;ft(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{Y(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e;ft(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{Y(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=L(e,t),{icons:n}=e;ft(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenWebOn),s=ft(t,o.fullscreenWebOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(Y(t,i.get("Exit Web Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(Y(t,i.get("Web Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenOn),s=ft(t,o.fullscreenOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(Y(t,i.get("Exit Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(Y(t,i.get("Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rqt.get(t).option.selector}),it(t,"$control_item",{get:()=>qt.get(t).item}),it(t,"$control_value",{get:()=>qt.get(t).value})),qt.set(t,e)}function Xt(t,e){t.innerHTML=e}function Gt(t,e,r,n,o){const{proxy:i}=t.events,a=E(n),s=r.selector;O(n,"art-control-selector");const l=document.createElement("div");O(l,"art-selector-value"),_(l,r.html),n.textContent="",_(n,l);const c=ft(n,'
');for(let u=0;u{if(a.closed)return;const o=S(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++d,c=()=>!a.closed&&s===d,p=a.add(function(t,e){return jt.set(t,e),()=>{jt.get(t)===e&&jt.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,i,i.$control_item,n);c()&&Xt(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Kt extends Ct{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;$(t,n);const{on:o}=L(t,n);o("mousemove",()=>{p||(this.show=!0)}),o("click",()=>{p?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=P(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(I(r,"art-hide-cursor"),O(r,"art-hover"),this.timer=Date.now()):(O(r,"art-hide-cursor"),I(r,"art-hover"))}),this.init(),b(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=E(e),{on:i}=L(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){Ht(this)}add(t){if(w(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:X(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Xt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Zt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(w(t))return;const n=P(r,e);t.isInput=n&&"INPUT"===r.target?.tagName,t.isFocus=n,t.emit(n?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),b(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(w(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),w(t))return;(!p||!t.isLock&&i)&&G(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),w(t))return;p?!t.isLock&&s&&G(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function Jt(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!w(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),b(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(w(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:It(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Vt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=J((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),p=J(i.time+t.duration*d*l,0,t.duration);t.seek=p,n(i)&&(t.emit("setBar","played",J(p/t.duration,0,1),o),n(i)&&(t.notice.show=`${tt(p)} / ${tt(t.duration)}`))},cancel:r}}const Qt=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],te=["resize","scroll","orientationchange"];const ee=new WeakMap;function re(t){const e=ee.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function ne(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=ne(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=re(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(o?.capture),once:Boolean(o?.once),passive:o?.passive,signal:o?.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||c?.aborted)return()=>{};let d=!0;function p(r=!1){(d||r)&&(e.removeEventListener(i,n,l),c?.removeEventListener("abort",u),d=!1,t.destroyEvents.delete(u))}function u(){p()}t.destroyEvents.add(u);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?p(!0):c?.aborted?u():c?.addEventListener("abort",u,{once:!0})}catch(h){try{p(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return u}function oe(t){return(e,r)=>{if(w(t))return;const n=(...e)=>{if(!w(t))return r(...e)};t.on(e,n),b(t).add(()=>{t.off(e,n)})}}function ie(t){if(!t.constructor.USE_RAF)return;const e=b(t);let r=()=>{};const n=()=>{w(t)||(t.playing&&t.emit("raf"),w(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),oe(t)("destroy",()=>r())}class ae{constructor(t){this.destroyEvents=new Set,function(t,e){ee.set(t,{scope:b(e),cleaning:!1})}(this,t),b(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Zt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{w(t)||(O(r,"art-hover"),t.emit("hover",!0,e))},e=>{w(t)||(I(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{w(t)||t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t,o=oe(t);o("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),w(t)||(t.aspectRatio=e,w(t)||(n.show=""))});const i=b(t);let a=()=>{};const s=()=>{w(t)||(a(),a=Pt(i,()=>t.emit("resize"),n.RESIZE_TIME))};o("window:orientationchange",s),o("window:resize",s);const l=t.template.$player.ownerDocument.defaultView?.screen?.orientation;"function"===typeof l?.addEventListener&&e.proxy(l,"change",s)}(t,this),function(t,e){if(!p||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=Jt(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=b(t),a=oe(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=o?.innerHeight||n.documentElement.clientHeight,a=o?.innerWidth||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),w(t)||(s=!0,Pt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;b(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){if(w(t))return;const a=++n,s={disposers:[]},l=()=>a!==n||w(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,a=i.window||n.ownerDocument?.defaultView||window,c=(n,o,i)=>{for(const a of o){if(l())return;s.disposers.push(e.proxy(n,a,e=>{r!==s||w(t)||t.emit(`${i}:${a}`,e)}))}};c(o,Qt,"document"),c(a,te,"window")}catch(d){throw o(s),d}if(l())return void o(s);const c=r;r=s,o(c)}i(),e.bindGlobalEvents=i}(t,this),ie(t)}proxy(t,e,r,n={}){return Array.isArray(e),ne(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=re(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function se(t){if(t&&1===t.nodeType)return t}function le(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const ce=new WeakMap;class de{constructor(t){this.art=t,this.keys={},ce.set(this,{subscribed:!1}),p||this.init()}init(){const t=this.art;if(w(t))return;const e=ce.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{G(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!w(t)){if(t.isFocus&&function(t,e){if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const r=function(t,e){const r=t.target;return 9===r?.nodeType?r:r?.ownerDocument||t.view?.document||e}(t,e);let n=se(r.activeElement);for(;n?.shadowRoot?.activeElement;)n=se(n.shadowRoot.activeElement);if(n&&le(n))return!1;const o=se(t.composedPath?.()[0])||se(t.target);return!o||!le(o)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const pe={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",pe);class ue{constructor(t){this.art=t,this.languages={"zh-cn":pe},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=st(this.languages,t)&&this.languages[t]||{}}get(t){return st(this.language,t)&&this.language[t]||t}update(t){this.languages=ct(this.languages,t),this.init()}}const he={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class fe{constructor(t){const e={...he,...t.option.icons};for(const r in e)it(this,r,{get:()=>B(r,e[r])})}}const me=new WeakMap;class ge extends Ct{constructor(t){super(t),this.name="info",me.set(this,{revision:0}),p||this.init()}init(){const t=me.get(this),e=++t.revision;if(t.scope?.dispose(),w(this.art)||t.revision!==e)return;const r=b(this.art).child();t.scope=r,r.add(()=>{t.scope===r&&(t.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!w(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const p=Array.from(s.querySelectorAll("[data-video]")),u=()=>e.dispose();t.on("destroy",u),e.add(()=>{t.off("destroy",u)});const h=()=>{try{for(const t of p){if(!n())return;const e=Reflect.get(c,t.dataset.video??"undefined");if(!n())return;const r="number"===typeof e?e.toFixed(2):e;if(!n())return;if(t.textContent!==r){const e=null==r?null:`${r}`;if(!n())return;t.textContent=e}}n()&&Pt(e,h,a.INFO_LOOP_TIME)}catch(t){o(t)}};n()&&h()}catch(i){o(i)}}(this.art,r,()=>{this.show=!1})}}class ve extends Ct{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{H(i,"display","none"),H(s,"display",null),w(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,y(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),w(t)||n.proxy(e.$state,"click",()=>{w(t)||G(t.play())})}}const we=new WeakMap;function xe(t){const e=we.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class ke{constructor(t){this.art=t,this.timer=null,we.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),b(t).add(()=>{t.off("destroy",e)}),b(t).add(()=>{this.destroy()})}destroy(){xe(this)}set show(t){if(w(this.art))return;const e=we.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){xe(this);const i=e.revision,a=()=>!w(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(O(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(w(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",w(this.art)||e.revision!==t||I(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else I(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function $e(t,e){return function(t,e){const r=ct(e,t);return r.container=t.container,o(r,Et)}(t,e)}function Ee({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Te(t,e){if(!Ee(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Ee(r)?r:void 0}const Ce=new WeakMap;function Le(t){return Ce.get(t)||0}function Se(t,e,r,n=!1){const o=e=>{w(t)||r(e)};t[n?"once":"on"](e,o),b(t).add(()=>{t.off(e,o)})}function Pe(t,e,r){for(const[n,o]of e){if(w(t)||r&&!r())return;t[n].show=o}}function Me(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=Ot(t),l=0;return{reset(){l=0,a?.dispose(),I(i,"art-error")},loadStart(){I(i,"art-error")},schedule(c){(async c=>{if(w(t))return;const d=Ot(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const p=d.child();a=p,p.add(()=>{a===p&&(a=void 0)});const u=()=>!w(t)&&!p.closed&&d===Ot(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}const ze=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],Ae=(()=>{if("undefined"===typeof document)return!1;const t=ze[0],e={};for(const r of ze){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Re={change:Ae.fullscreenchange,error:Ae.fullscreenerror},Oe={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Oe.off("change",o),r()};Oe.on("change",o);const i=t[Ae.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Oe.isFullscreen)return void t();const r=()=>{Oe.off("change",r),t()};Oe.on("change",r);const n=document[Ae.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Oe.isFullscreen?Oe.exit():Oe.request(t,e),onchange(t){Oe.on("change",t)},onerror(t){Oe.on("error",t)},on(t,e){const r=Re[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Re[t];r&&document.removeEventListener(r,e,!1)},raw:Ae};function Ie(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(Oe,{isFullscreen:{get:()=>Boolean(document[Ae.fullscreenElement])},element:{enumerable:!0,get:()=>document[Ae.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Ae.fullscreenEnabled])}});const Ne=new WeakMap;function _e(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function We(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ne.get(t);if(!n){n=new WeakMap,Ne.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),_e(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),_e(i))}function De(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,p=!1,u=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!p&&r&&We(t))});const m=()=>{d&&!p&&(r?t.element===t.target:o())&&f()};if(St(i,t.document,t.changeEvent,m),St(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(u=!0,d&&!p&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){Ne.get(t.document)?.delete(t.target)}(t);const e=r?t.request():t.exit();p=Boolean(e&&"function"===typeof e.then),d=!0,c&&!p&&r&&We(t),p?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):u?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Fe(t,e){const r=b(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,p=!1,u=!1;function h(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),h()}),St(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return Ne.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void h();if(r===s||w(t))return;s=r;const o=l,a=()=>w(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),St(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(u||void 0!==a||i()))&&!w(t)&&t.emit("fullscreenError",r)}),{get:()=>!w(t)&&i(),set(n){if(w(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?p=!1:d&&(p=!0),a?.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();u=!0,d=c;const s=De(e,r,c,()=>{!w(t)&&c||h()},()=>!i());u=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw w(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const Ve=new WeakSet;function Ye(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Be(t){Ve.delete(t),t.removeEventListener("webkitbeginfullscreen",He),t.removeEventListener("webkitpresentationmodechanged",He)}function He(t){if(Ve.has(this)&&Ye(this,"webkitbeginfullscreen"===t.type)){Be(this);try{this.webkitExitFullscreen?.()}catch{}}}function je(t){Ve.add(t),t.addEventListener("webkitbeginfullscreen",He),t.addEventListener("webkitpresentationmodechanged",He)}function qe(t){const{$video:e}=t.template,r=b(t).child();let n=!1,o=Ye(e),i=o,a=!1,s=0;const l=()=>Ye(e,n);function c(r){if(w(t)||(c=e,Ve.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const p=s,u=()=>w(t)||l()!==d||p!==s&&i!==d;t.emit("fullscreen",d),u()||(d&&(t.state="fullscreen"),u()||t.emit("resize"))}r.add(()=>{s++,i=!1,a&&je(e),l()&&e.webkitExitFullscreen?.()}),St(r,e,"webkitbeginfullscreen",()=>c(!0)),St(r,e,"webkitendfullscreen",()=>c(!1)),St(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!w(t)&&l(),set(r){if(w(t))return;const n=++s;if(i=Boolean(r),r){if(Be(e),t.state="fullscreen",w(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,je(e)),l()&&e.webkitExitFullscreen()}}}function Ue(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Xe({node:t,parent:e,next:r}){if(!e)return void t.parentNode?.removeChild(t);const n=r?.parentNode===e?r:null;t.parentNode===e&&t.nextSibling===n||e.insertBefore(t,n)}function Ge(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function Ke(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Ze(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),St(o,e,"click",n),St(o,l,"click",()=>{G(t.play())}),St(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const p=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};St(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=Ge(i.left,i.top,Ke(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:p,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function Je(t){const{$player:e,$video:r}=t.template,n=b(t).child();let o,i,a=0,s=!1,l=!1;const c=()=>!w(t)&&e.classList.contains("art-mini");function d(){if(i){const e=i,r=a;i=void 0;try{Xe(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(w(t))return;const r=++a;l=!1,d(),w(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function u(){if(w(t))return;const h=++a;if(s)l=!0;else if(t.state="mini",!w(t)&&h===a){i??(i=Ue(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Ze(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void u();if(!o||w(t))return;if(h!==a)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),w(t)||h!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:{...Ge(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,Ke(o.element));if(w(t)||h!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),w(t)||h!==a)return;t.storage.set("left",i.left)}w(t)||h!==a||t.emit("mini",!0)}catch(f){const r=l;throw l=!1,w(t)||h!==a&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),f}}}return n.add(()=>{a++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?u():p()}}}const Qe=new WeakSet,tr=t=>"picture-in-picture"===t.webkitPresentationMode;function er(t){Qe.delete(t),t.removeEventListener("webkitpresentationmodechanged",rr),t.removeEventListener("enterpictureinpicture",rr)}function rr(){if(Qe.has(this)&&tr(this)){er(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function nr(t){Qe.add(t),t.addEventListener("webkitpresentationmodechanged",rr),t.addEventListener("enterpictureinpicture",rr)}function or(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function ir(t,e,r){return new Promise((n,o)=>{if(w(t)||e===t.url)return void n();const i=Nt(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),d=t=>l(!0,t);i.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child();let u=!1,h=!1,f=!1;const m=function(t,e,r){let n,o=!1,i=!1,a=!1,s=Le(t);const l=()=>a||Le(t)!==s,c=()=>!!t.template?.$video?.seeking;return{restore(){if(!r()||l())return;const i=Le(t);t.currentTime=e,s=Le(t),s>i+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}(t,r,c),g=async()=>{if(t.aspectRatio=o,c()){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}},v=()=>{if(c()&&!h&&u)try{if(t.template?.$video?.seeking)return;if(!c())return;if(f||(f=!0,t.playbackRate=s),!m.ready()||!c()||h)return;h=!0,p.dispose(),g().catch(d)}catch(e){d(e)}},y={"video:error":d,"video:loadedmetadata":()=>{if(c())try{m.restore()}catch(t){d(t)}},"video:canplay":()=>{u=!0,v()},"video:seeked":v,seek:m.manual},b=a.child(),w=[],x=Object.keys(y);for(const e of x)or(b,t,e,t=>{i.acceptingEvents&&w.push([e,t])},!1);if(Wt(t,i,e),!c())return;if(t.notice.show="",!c())return;const k=()=>{if(b.dispose(),!e)return void l();const r={};for(const e of x)r[e]=or(p,t,e,y[e],"video:seeked"!==e);for(const[t,e]of w){if(!c()||p.closed)break;r[t](e)}w.length=0};i.assigned?k():i.onAssigned=k}catch(p){d(p)}})}function ar(t,e){const{number:r,column:n,width:o,height:i,scale:a}=t,{imageWidth:s,videoWidth:l,videoHeight:c,progressWidth:d,position:p}=e,u=Number(n),h=Number(o)*Number(a)||s/u,f=Number(i)*Number(a)||h/(l/c),m=Math.floor(p/(d/Number(r)));return{height:`${f}px`,width:`${h}px`,backgroundPosition:`-${m%u*h}px -${Math.floor(m/u)*f}px`,left:p<=h/2?0:p>d-h/2?d-h+"px":p-h/2+"px"}}function sr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(w(t))return;const o=function(t){const e=At.get(t);return At.delete(t),e||Nt(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await Mt(o.scope)&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||K(n),s=e.customType[a];if(a&&s){if(!(await Mt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;or(l,t,"video:canplay",()=>{c=!d}),or(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Dt(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||or(o.scope,t,"video:canplay",e)}}catch(i){Dt(o,i)}finally{_t(o)}}})}const lr=[function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){const n=e;if(void 0===r)return n[t];n[t]=r}})},function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=It(t),s=await i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})},function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${tt(t.currentTime)} / ${tt(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;it(t,"forward",{set(e){r.seek=t.currentTime+e}}),it(t,"backward",{set(e){r.seek=t.currentTime-e}})},function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=J(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),it(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})},function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){Ce.set(t,Le(t)+1)}(t),e.currentTime=J(n,0,t.duration))}})},function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})},function(t){const e=e=>ir(t,e,0);it(t,"switchQuality",{value:e=>ir(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})},function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;it(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!w(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Te({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(w(t))return;"width"===r?.axis?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,w(t)||t.emit("aspectRatio",i)}}})},function(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=It(t);return new Promise((a,s)=>{const l=r=>{try{!w(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}it(t,"getDataURL",{value:()=>o(!1)}),it(t,"getBlobUrl",{value:()=>o(!0)}),it(t,"screenshot",{value:async e=>{const n=It(t),o=await t.getDataURL();if(!w(t)&&n()){const i=e||`artplayer_${tt(r.currentTime)}`;!w(t)&&n()&&Z(o,`${i}.png`),!w(t)&&n()&&t.emit("screenshot",o)}return o}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(w(t))return;const i=function(t){const e=Oe.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>Ie(t,e.requestFullscreen,void 0),exit:()=>Ie(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",Fe(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",qe(t)):it(t,"fullscreen",{get:()=>!1,set(){w(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",lt(t,"fullscreen"))};t.once("video:loadedmetadata",i),b(t).add(()=>{t.off("video:loadedmetadata",i)})},function(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(Xe(t.placement),r()))}return b(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(i){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(a){throw new f([i,a])}throw i}}),i=>{if(w(t))return;const a=++n,s=()=>a===n&&!w(t);if(i){r||(r={placement:Ue(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);it(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})},function(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?it(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=b(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function p(e,r,n){e.then(()=>{!r||!w(t)&&a||d()},e=>{w(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),St(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!w(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),St(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!w(t)&&o()?e:null,set(n){if(w(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",w(t)||c!==i)return;s=!0;try{p(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&p(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=b(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(w(t)||Qe.has(e))return;const s=tr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),w(t)||i!==l||tr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&nr(e),tr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])St(r,e,l,()=>s());return{get:()=>!w(t)&&tr(e),set(r){if(w(t))return;const n=++i,l=a;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(er(e),t.state="pip",w(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===i&&(o=!1),c}}else o&&(o=!1,nr(e)),tr(e)&&e.webkitSetPresentationMode("inline");w(t)||n!==i||l!==a||tr(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){w(t)||(r.show=e.get("PIP Not Supported"))}})},function(t){const{$video:e}=t.template,r=t;it(t,"loaded",{get:()=>r.loadedTime/e.duration}),it(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})},function(t){it(t,"played",{get:()=>t.currentTime/t.duration})},function(t){const{$video:e}=t.template;it(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})},function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(w(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Ee(o))return;const i=z(e),a=Te(i,o.width/o.height);a&&!w(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})},function(t){const e=t;it(t,"rect",{get:()=>z(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}it(t,"x",{get:()=>e.left+window.pageXOffset}),it(t,"y",{get:()=>e.top+window.pageYOffset})},function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){w(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,w(t)||t.emit("flip",o))}})},function(t){it(t,"mini",Je(t))},function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){H(e,"backgroundImage",`url(${t})`)}})},function(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(w(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Ee(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||w(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})},function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})},function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})},function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})},function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];it(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;nn.$track?.offset||0,set(o){const{cues:i}=t.subtitle;if(!n.$track||0===i.length)return;const a=J(o,-10,10);n.$track.offset=a;for(let e=0;e{if(!w(t))switch(e.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,w(t)||it(t,"airplay",{value(){if(!w(t))if(i){const e=o.webkitShowPlaybackTargetPicker;if(w(t))return;Reflect.apply(e,o,[]),w(t)||t.emit("airplay")}else{const n=e.get("AirPlay Not Available");w(t)||(r.show=n)}}}))},function(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:i?.html||"",selector:e,async onSelect(e,r,i){const a=function(t){return t&&jt.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!w(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!w(t)&&a()&&(n.show=r)}return e.html}})}})},function(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,s=b(t).child(),l=!1;function c(){const e=s;s=b(t).child(),o=void 0,l=!1,a=void 0,e.dispose()}function d(){const i=a,l=s;if(!i||!o)return;const c=()=>!w(t)&&!l.closed&&s===l&&a===i&&i.sourceActive()&&t.controls?.thumbnails===i.element;if(!c())return;const d=r.clientWidth*i.percentage;if(!(d>0&&d{const h=t.controls?.thumbnails,{url:f,scale:m}=e.thumbnails;if(!w(t)&&h&&f&&("hover"===r||"played"===r&&u&&p)){if(i!==h){const t=E(h);if(t.closed)return;i=h,t.add(()=>{i===h&&(i=void 0,c())})}if(a={percentage:n,element:h,sourceActive:It(t)},o)d();else if(!l){const t=s;l=!0,function(t,e,r){return q(t,e,r)}(f,m,t).then(e=>{s!==t||t.closed||(l=!1,o=e,d())}).catch(e=>{s!==t||t.closed||(l=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{w(t)||!e.url||t.option.isLive||w(t)||(t.option.thumbnails=e,c())}})},function(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{w(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Me(t);!function(t,e){Se(t,"video:canplay",()=>{e.reset(),Pe(t,[["loading",!1]])}),Se(t,"video:canplay",()=>{Pe(t,[["loading",!1],["controls",!0],["mask",!0]]),w(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Se(t,"video:ended",()=>{if(e.loop){const e=It(t);if(t.seek=0,w(t)||!e())return;G(t.play()),e()&&Pe(t,[["controls",!1],["mask",!1]],e)}else Pe(t,[["controls",!0],["mask",!0]])})}(t),Se(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Se(t,"video:loadedmetadata",()=>{t.emit("resize"),p&&Pe(t,[["loading",!1],["controls",!0],["mask",!0]])}),Se(t,"video:loadstart",()=>{e.loadStart(),Pe(t,[["loading",!0],["mask",!1],["controls",!0]])}),Se(t,"video:pause",()=>{Pe(t,[["controls",!0],["mask",!0]])}),Se(t,"video:play",()=>{Pe(t,[["mask",!1]]),w(t)||H(r,"display","none")}),Se(t,"video:playing",()=>Pe(t,[["mask",!1]])),Se(t,"video:progress",()=>{t.playing&&Pe(t,[["loading",!1]])}),Se(t,"video:seeked",()=>Pe(t,[["loading",!1],["mask",!0]])),Se(t,"video:seeking",()=>Pe(t,[["loading",!0],["mask",!1]])),Se(t,"video:timeupdate",()=>Pe(t,[["mask",!1]])),Se(t,"video:waiting",()=>Pe(t,[["loading",!0],["mask",!1]]))}(t,e)},function(t){if(w(t))return;const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const s in e.moreVideoAttr){if(w(t))return;const r=e.moreVideoAttr[s];if(w(t))return;t.attr(s,r)}if(w(t))return;if(e.muted){const r=e.muted;if(w(t))return;t.muted=r}if(w(t))return;if(e.volume){const r=J(e.volume,0,1);if(w(t))return;n.volume=r}if(w(t))return;const i=r.get("volume");if(w(t))return;if("number"===typeof i&&(n.volume=J(i,0,1)),w(t))return;if(e.poster){const r=`url(${e.poster})`;if(w(t))return;H(o,"backgroundImage",r)}if(w(t))return;if(e.autoplay){const r=e.autoplay;if(w(t))return;n.autoplay=r}if(w(t))return;if(e.playsInline){if(w(t))return;if(n.playsInline=!0,w(t))return;n["webkit-playsinline"]=!0}if(w(t))return;if(e.theme){const r=e.cssVar,n=e.theme;if(w(t))return;r["--art-theme"]=n}for(const s in e.cssVar){if(w(t))return;const r=e.cssVar[s];if(w(t))return;t.cssVar(s,r)}if(w(t))return;const a=e.url;w(t)||(t.url=a)}];class cr{constructor(t){if(!w(t)){sr(t);for(const e of lr){if(w(t))return;e(t)}}}}const dr=new WeakMap,pr="art-auto-orientation-fullscreen";function ur(t){if(dr.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const hr="art-auto-orientation",fr=["width","height","transform-origin","transform"];function mr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Ee(t)&&Ee(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=b(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(hr);r.classList.remove(hr),n&&(t.isRotate=!1,w(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=A();if(w(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=fr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(hr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{w(t)||(r?o?s(!1):e()&&(i(),i=Pt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(pr),t&&(t.cancelled=!0,ur(t),t.settled&&dr.get(t.orientation)===t&&dr.delete(t.orientation))}return b(t).add(o),i=>{if(w(t))return;if(!i)return void o();if(n&&!n.cancelled&&dr.get(n.orientation)===n)return;const a=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof a?.lock||"function"!==typeof a.unlock||!e())return;const s={orientation:a,cancelled:!1,settled:!1};n=s,dr.set(a,s);const l=()=>!w(t)&&!s.cancelled&&n===s&&dr.get(a)===s,c=e=>{s.settled=!0;const o=l();dr.get(a)===s&&dr.delete(a),n===s&&(n=void 0),o&&(r.classList.remove(pr),t.notice.show=e)};try{const t=a.lock(a.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,l()?r.classList.add(pr):(ur(s),dr.get(a)===s&&dr.delete(a))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),b(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function gr(t){return t.get("times")||{}}function vr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||w(t))return()=>{};const s=mt(".art-auto-playback-last",a),l=mt(".art-auto-playback-jump",a),c=mt(".art-auto-playback-close",a);ft(c,r.close);const d=E(a);let p,u=0;const h=()=>{const r=++u;if(p?.dispose(),d.closed||w(t)||u!==r)return;const h=d.child();p=h;const f=()=>p===h&&!h.closed&&!w(t);h.add(()=>{p===h&&(p=void 0,H(a,"display","none"))});const m=Ot(t).add(()=>{h.dispose()});h.add(()=>{m()});const g=gr(n)[t.option.id||t.option.url];if(!f())return;if(H(a,"display","none"),!f()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!f())return;if(H(a,"display","flex"),!f())return;const v=`${e.get("Last Seen")} ${tt(g)}`;if(!f())return;if(s.textContent=v,!f())return;const y=e.get("Jump Play");if(!f())return;if(l.textContent=y,!f())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{f()&&r()});h.add(()=>{t.events.remove(n)})};if(b(c,()=>{H(a,"display","none")}),!f())return;if(b(l,()=>{t.seek=g,f()&&(G(t.play()),f()&&(H(i,"display","none"),f()&&H(a,"display","none")))}),!f())return;let x=()=>{},k=!1;const $=()=>{!k&&f()&&(k=!0,x(),Pt(h,()=>{f()&&H(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",$),x=h.add(()=>{t.off("video:timeupdate",$)}),k&&x()};return()=>{C(t,a,"ready",h),C(t,a,"restart",h)}}(t);return function(t){const{storage:e,constructor:r}=t;oe(t)("video:timeupdate",()=>{if(!t.playing)return;const n=gr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;w(t)||(o.length>i&&delete n[o[0]],n[a]=s,w(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return gr(e)},clear:()=>e.del("times"),delete(t){const r=gr(e);return delete r[t],e.set("times",r),r}}}function yr(t){let e,r=0;return{start:n=>{const o=++r;if(e?.scope.dispose(),o!==r||w(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:Ot(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{e?.active||I(t.template.$player,"art-fast-forward")}}),Pt(i.scope,()=>{if(e!==i||w(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||w(t))return;t.playbackRate=r,e!==i||i.scope.closed||w(t)||O(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,e?.scope.dispose()}}}function br(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=yr(t),i=oe(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return N(r,"art-fast-forward")}}}function wr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return N(n,"art-lock")}function i(){w(t)||(O(n,"art-lock"),w(t)||(t.isLock=!0,w(t)||t.emit("lock",!0)))}function a(){w(t)||(I(n,"art-lock"),w(t)||(t.isLock=!1,w(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=E(e);if(n.closed||w(t))return;const o=ft(e,r.lock);if(n.closed||w(t))return;const i=ft(e,r.unlock);n.closed||w(t)||(H(o,"display","none"),C(t,e,"lock",e=>{w(t)||(H(o,"display",e?"inline-flex":"none"),n.closed||w(t)||H(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function xr(t){return oe(t)("control",e=>{e?I(t.template.$player,"art-mini-progress-bar"):O(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class kr{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){w(t.art)||!e.miniProgressBar||e.isLive||t.add(xr),!w(t.art)&&e.lock&&p&&t.add(wr),w(t.art)||!e.autoPlayback||e.isLive||t.add(vr),!w(t.art)&&e.autoOrientation&&p&&t.add(mr),!w(t.art)&&e.fastForward&&p&&!e.isLive&&t.add(br)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!w(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(w(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(w(t.art))return t;let o=n;const i=st(t,o);if(w(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return w(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),w(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const $r=new WeakMap;function Er(t){return!t.closed&&!$r.get(t)}function Tr(t){$r.set(t,($r.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=($r.get(t)||1)-1;r?$r.set(t,r):$r.delete(t)}}const Cr=new WeakMap,Lr=new WeakMap,Sr=["$parent","$parents","$option","$events","$formatted"];function Pr(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=Cr.get(r);if(!t||!t.owner.active||t.owner.scope?.closed||!t.option.includes(r))return!1;if(!t.parent)return t.owner.root===t.option;if(Cr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function Mr(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function zr(t){const e=Cr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Ar(t,e){for(let r=0;r{c&&c!==r&&c.dispose()},()=>Dr(t,o)])try{e()}catch(d){d instanceof f?l.push(...d.errors):l.push(d)}if(r.closed||w(t)||(o.push(...i.splice(0)),Wr.set(r,o),Nr.set(e,r),_r.set(e,n)),a(),l.length)throw new f(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function Hr(t,e,r,n,o,i){const a=i||Vr(e);if(!Er(a)||w(t))return;const s=t.proxy(r,n,e=>{if(Er(a)&&!w(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Er(a)||w(t)?t.events.remove(s):(zr(e).events.push(s),i&&i!==Nr.get(e)&&i.add(()=>{const r=zr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function jr(t,e,r,n){const o=Vr(e);if(!Er(o)||w(t))return;const i=(...e)=>{if(Er(o)&&!w(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function qr(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:i},template:{$player:a,$setting:s,$bottom:l}}=e;if(!n.setting||!t.show||!r)return;const c=a.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),u=c.width/a.offsetWidth||1,h=(d.left-c.left+d.width/2)/u-a.clientLeft,f=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:a.clientWidth,containerHeight:a.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:i,controlCenter:h,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${f.height}px`,s.style.width=`${f.width}px`,e.isRotate||p||(h+f.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${f.left}px`,s.style.right="auto"))}const Ur=new WeakMap;function Xr(t){Ur.delete(t)}const Gr=new WeakMap;function Kr(t,e){e?Gr.set(t,e):Gr.delete(t)}function Zr(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=Gr.get(t),o=n?.();for(const i of["html","icon","tooltip"]){const t=e.get(i)?.value;t instanceof Node&&r.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{for(const r of Reflect.ownKeys(t))!e.has(r)&&Object.getOwnPropertyDescriptor(t,r)?.configurable&&Reflect.deleteProperty(t,r);for(const[r,n]of e)Object.defineProperty(t,r,n);o?.(),Kr(t,n);for(const{node:t,parent:e,next:n}of r)e?e.insertBefore(t,n?.parentNode===e?n:null):t.parentNode?.removeChild(t)}}const Jr=new WeakMap;async function Qr(t,e,r,n,o,i,a,s){try{const l=Vr(e),c=Vr(i),d=(Jr.get(i)||0)+1;Jr.set(i,d);const p=()=>Er(l)&&Er(c)&&!w(t.art)&&Jr.get(i)===d;if(s?.(),!p())return;const u=await o.call(t.art,e,r,n);p()&&Reflect.set(i,a,u)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}}function tn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const en=new WeakMap;function rn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof f?e.push(...r.errors):e.push(r)}if(e.length)throw new f(e)}function nn(t){en.get(t)?.()}function on(t,e){const r=t.find(e.name);if(w(t.art))return r||e;if(!r)return t.add(e);Xr(r),nn(r);const n=Zr(r),o=r.$item,i=o?.parentNode,a=o?.nextSibling,s=o?tn(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=Br(t.art,e);r&&i.push(r)}for(const t of n)a.push(Tr(Or(t)))}catch(l){try{rn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,rn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,rn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Ir(t)),...a]))}}}(t,r);let p=!0,u=!1;const h=()=>{if(!p)return;p=!1;for(const t of d.items)en.get(t)===h&&en.delete(t);if(w(t.art))return void d.dispose();const e=r.$item;try{rn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{i&&o&&i.insertBefore(o,a?.parentNode===i?a:null)},()=>t.format(),()=>{if(u){t.active=l,l&&t.cache.has(l)&&D(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(f){console.warn("ArtPlayer setting restore failed:",f)}},f=()=>p&&!w(t.art)&&en.get(r)===h;for(const v of d.items)en.set(v,h);const m=b(t.art).add(()=>{p=!1;for(const t of d.items)en.get(t)===h&&en.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!o?.enumerable||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,f),!f())return r;if(t.format(),!f())return r;if(t.createItem(r,!0),!f())return r;if(u=!0,t.render(),!f())return r;p=!1;for(const t of d.items)en.get(t)===h&&en.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const an=new WeakMap;function sn(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",_(r,t)}})}function ln(t,e,r=!1){const n=function(t){const e=en.get(t);return()=>!e||en.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),i=e.$item;let a="selector";st(e,"switch")&&(a="switch"),st(e,"range")&&(a="range"),st(e,"onClick")&&(a="button");const{icons:s,constructor:l}=t.art;if(!n())return;const c=function(t,e,r=b(t)){const n=Nr.get(e);(!n||Er(n)||n.closed)&&Yr(t,e);const o=r.child();return Nr.set(e,o),_r.set(e,r),Wr.set(o,zr(e).events),o.add(()=>{Dr(t,Wr.get(o))}),o}(t.art,e,Or(o)),d=()=>Er(c)&&!w(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(Kr(e),O(p,"art-setting-item"),H(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=ft(p,'
'),u=ft(p,'
'),h=document.createElement("div");switch(O(h,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;_(h,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;_(h,t)}else _(h,s.check)}if(_(n,h),!d())return;sn(e,"icon",h);const f=document.createElement("div");O(f,"art-setting-item-left-text");const m=e.html||"";if(!d())return;_(f,m),_(n,f),sn(e,"html",f);const g=document.createElement("div");O(g,"art-setting-item-right-tooltip");const v=e.tooltip||"";if(!d())return;switch(_(g,v),_(u,g),sn(e,"tooltip",g),a){case"switch":{const t=document.createElement("div");O(t,"art-setting-item-right-icon");const r=ft(t,s.switchOn),n=ft(t,s.switchOff),o=e.switch;if(!d())return;H(o?n:r,"display","none"),_(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;Kr(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(H(n,"display","none"),H(r,"display",null)):(H(n,"display",null),H(r,"display","none"))}});break}case"range":{const t=document.createElement("div");O(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",_(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,i,String(t))}O(r,"art-setting-range"),_(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Kr(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),it(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(e.selector?.length){const t=document.createElement("div");O(t,"art-setting-item-right-icon"),_(t,s.arrowRight),_(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=Vr(e),a=(t,r,n)=>Hr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>Qr(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>Qr(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return Qr(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&O(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>Qr(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,p,a),!d())return;it(e,"$item",{configurable:!0,get:()=>p}),r&&i?.parentNode?i.replaceWith(p):_(o,p),e.mounted&&d()&&Pt(c,()=>{if(!w(t.art))try{const r=e.mounted?.call(t.art,p,e);Promise.resolve(r).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(r){console.warn("ArtPlayer setting mounted failed:",r)}},0)}catch(u){try{c.dispose()}catch(h){console.warn("ArtPlayer setting cleanup failed:",h)}throw p.remove(),u}}function cn(t,e=t.option){if(w(t.art))return;const r=t.cache.get(e);if(r&&!Er(Or(r)))return;const n=(an.get(t)||0)+1;an.set(t,n);const o=()=>an.get(t)===n&&!w(t.art),i=t.active,a=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),s=()=>{t.active=i,i&&t.cache.has(i)&&D(t.cache.get(i),"art-current");for(const[e,r,n]of a)t.$parent.style.setProperty(e,r,n)};if(t.active=e,r)try{D(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!Or(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=b(t.art).child();return Rr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),i=()=>!n.closed&&!w(t.art)&&t.cache.get(e)===r,a=[];try{if(!i())return;O(r,"art-setting-panel"),_(t.$parent,r),D(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Lr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=b(e).child(),n=(t,n)=>{if(r.closed||w(e))return;const o=(...t)=>{if(!r.closed&&!w(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=P(r,e.controls.setting),o=P(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||w(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),jr(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),jr(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(Q(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),jr(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{jr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Ar(e,t)}check(t){!function(t,e){e?.$parent&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&D(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Lr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nzr(t).parent},$parents:{get:()=>zr(t).parents},$option:{get:()=>zr(t).option},$events:{get:()=>zr(t).events},$formatted:{get:()=>!0}}),Cr.set(t,{parent:r,parents:n,option:o,events:a?.events||[],owner:i}),p.generated&&(t.name=e)}for(const p of a)p.generated||o.push(p.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Ar(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){qr(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Ir(n)}catch(i){r.push(i)}}try{Yr(t.art,e)}catch(i){i instanceof f?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new f(r)}(this,t)}remove(t){const e=this.find(t);X(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Xr(t),nn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>n?.remove(),()=>this.render()])try{a()}catch(i){i instanceof f?o.push(...i.errors):o.push(i)}if(o.length)throw new f(o)}update(t){return on(this,t)}add(t,e=this.option){if(w(this.art))return t;let r=!1;this.traverse(e=>{r||(r=e===t)});const n=e.length,o=r?void 0:function(t){const e={};Ur.set(t,e);const r=()=>Ur.get(t)===e;return{current:r,finish(){r()&&Ur.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(w(this.art)||o&&!o.current())throw a;if(e[n]===t&&e.splice(n,1),!r&&i){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw a}finally{o?.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");H(i,"height",`${o}px`),O(i,"art-setting-item"),O(i,"art-setting-item-back");const a=ft(i,'
'),s=document.createElement("div");O(s,"art-setting-item-left-icon"),_(s,n),_(a,s),_(a,e.$parent.html),Hr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Or(r)),_(r,i)}(this,t)}createItem(t,e=!1){ln(this,t,e)}render(t=this.option){cn(this,t)}}class un{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch{return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch{this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch{delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch{this.settings={}}}}const hn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class fn{constructor(t){this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope)?.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}async run(t){if(this.active)try{return await Promise.race([t(),this.cancelled])}finally{this.cancel()}}}const mn=new WeakMap;function gn(t){return mn.get(t)}function vn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const yn=Ct;class bn extends yn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=b(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return mn.set(t,n),r.add(()=>{vn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){return this.art.template.$video?.textTracks?.[0]}get activeCues(){return Array.from(this.textTrack?.activeCues||[])}get cues(){return Array.from(this.textTrack?.cues||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?j(r,t):H(r,t,e)}update(){!function(t){const e=gn(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?ot(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i={...o.subtitle,...e,url:t},a=gn(this),s=a.revision+1,l=await this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),l}createTrack(t,e){!function(t,e,r){const n=gn(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),p=n.scope.child();p.add(()=>{d.onload=null,d.onerror=null});let u=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{p.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{p.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},p.closed||n.trackRevision!==o)return void p.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{p.closed||a.$track!==d||t.update()}):()=>{};if(p.add(()=>{i.events.remove(c)}),p.closed||n.trackRevision!==o)return p.dispose(),void d.remove();const h=n.track;n.track=p,t.destroyEvent=c,s.onload=null,s.onerror=null,u=!0;try{h?.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&vn(n)}}catch(h){if(u)throw h;if(p.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,c?.parentNode===l?c:null),h}}(this,t,e)}async init(t){const e=gn(this),r=function(t){const e=t.request,r=new fn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:i}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Et.subtitle),!t.url)return;let a;this.option=t,this.style(t.style);try{if(!r.active)return;const n=await fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const o=await n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||K(e.url)){case"srt":return{vtt:e.onVttLoad(dt(r))};case"ass":return{vtt:e.onVttLoad(ut(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const l=void 0===s?t.url:a=pt(s.vtt);if(!r.active)return;i.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return a&&(e.ownedURL=a,a=void 0),l}catch(s){if(!r.active)return;throw i.innerHTML="",n.show=s,s}finally{a&&(e.scope.closed||this.url!==a?URL.revokeObjectURL(a):e.ownedURL=a)}})}}const wn=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${i}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class xn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=R(e.container),X(this.$container,`No container element found by ${e.container}`)),X(M(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();X("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),X(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=v.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=y(t);o.rollback=r,v.set(e,t),o.releaseContainer=()=>{v.get(e)===t&&v.delete(e)}}(t,this.$container,tn(this.$container)),function(t,e,r){const n=y(t),o=n.mountingTemplate;n.mountingTemplate=e;try{r()}finally{n.mountingTemplate=o}}(t,this,()=>{this.$container.dataset.artId=String(t.id),this.init()})}static get html(){return wn}query(t){return R(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=xn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);if(w(this.art))return;!function(t){X(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),F(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&O(this.$player,"art-backdrop"),p&&O(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":O(this.$player,"art-destroy")}}const kn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class $n{on(t,e,r){const n=this.e||(this.e={});let o=kn(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(kn(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=kn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new xn(this),b(this).closed)return;if(this.events=new ae(this),b(this).closed)return;if(this.storage=new un,b(this).closed)return;if(this.icons=new fe(this),b(this).closed)return;if(this.i18n=new ue(this),b(this).closed)return;if(this.notice=new ke(this),b(this).closed)return;if(this.player=new cr(this),b(this).closed)return;if(this.layers=new ve(this),b(this).closed)return;if(this.controls=new Kt(this),b(this).closed)return;if(this.contextmenu=new Lt(this),b(this).closed)return;if(this.subtitle=new bn(this),b(this).closed)return;if(this.info=new ge(this),b(this).closed)return;if(this.loading=new ye(this),b(this).closed)return;if(this.hotkey=new de(this),b(this).closed)return;if(this.mask=new be(this),b(this).closed)return;if(this.setting=new pn(this),b(this).closed)return;if(this.plugins=new kr(this),b(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Cn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Cn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=y(t);return e.rollback=void 0,!e.scope.closed})(this)&&Tn.push(this)}catch(r){try{x(this,Tn,!0,Cn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return Tn}static get version(){return i}static get config(){return h}static get utils(){return ht}static get scheme(){return Et}static get Emitter(){return $n}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return xn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:l?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:navigator?.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){x(this,Tn,t,Cn.REMOVE_SRC_WHEN_DESTROY)}}var Ln,Sn;return Cn.STYLE=hn,Cn.DEBUG=!1,Cn.CONTEXTMENU=!0,Cn.NOTICE_TIME=2e3,Cn.SETTING_WIDTH=250,Cn.SETTING_ITEM_WIDTH=200,Cn.SETTING_ITEM_HEIGHT=35,Cn.RESIZE_TIME=200,Cn.SCROLL_TIME=200,Cn.SCROLL_GAP=50,Cn.AUTO_PLAYBACK_MAX=10,Cn.AUTO_PLAYBACK_MIN=5,Cn.AUTO_PLAYBACK_TIMEOUT=3e3,Cn.RECONNECT_TIME_MAX=5,Cn.RECONNECT_SLEEP_TIME=1e3,Cn.CONTROL_HIDE_TIME=3e3,Cn.DBCLICK_TIME=300,Cn.DBCLICK_FULLSCREEN=!0,Cn.MOBILE_DBCLICK_PLAY=!0,Cn.MOBILE_CLICK_PLAY=!1,Cn.AUTO_ORIENTATION_TIME=200,Cn.INFO_LOOP_TIME=1e3,Cn.FAST_FORWARD_VALUE=3,Cn.FAST_FORWARD_TIME=1e3,Cn.TOUCH_MOVE_RATIO=.5,Cn.VOLUME_STEP=.1,Cn.SEEK_STEP=5,Cn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Cn.ASPECT_RATIO=["default","4:3","16:9"],Cn.FLIP=["normal","horizontal","vertical"],Cn.FULLSCREEN_WEB_IN_BODY=!0,Cn.LOG_VERSION=!0,Cn.USE_RAF=!1,Cn.REMOVE_SRC_WHEN_DESTROY=!0,Ln=Cn,Sn=hn,u&&(window.Artplayer=Ln,a("artplayer-style",Sn),setTimeout(()=>{Ln.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Ln.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Cn}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),c=/^(?:(?!chrome|android).)*safari/i.test(s),l=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=l||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,u=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,p="undefined"!==typeof window&&"undefined"!==typeof document;const f={properties:["audioTracks","autoplay","buffered","controller","controls","crossOrigin","currentSrc","currentTime","defaultMuted","defaultPlaybackRate","duration","ended","error","loop","mediaGroup","muted","networkState","paused","playbackRate","played","preload","readyState","seekable","seeking","src","startDate","textTracks","videoTracks","volume"],methods:["addTextTrack","canPlayType","load","play","pause"],events:["abort","canplay","canplaythrough","durationchange","emptied","ended","error","loadeddata","loadedmetadata","loadstart","pause","play","playing","progress","ratechange","seeked","seeking","stalled","suspend","timeupdate","volumechange","waiting"],prototypes:["width","height","videoWidth","videoHeight","poster","webkitDecodedFrameCount","webkitDroppedFrameCount","playsInline","webkitSupportsFullscreen","webkitDisplayingFullscreen","onenterpictureinpicture","onleavepictureinpicture","disablePictureInPicture","cancelVideoFrameCallback","requestVideoFrameCallback","getVideoPlaybackQuality","requestPictureInPicture","webkitEnterFullScreen","webkitEnterFullscreen","webkitExitFullScreen","webkitExitFullscreen"]};class h extends Error{constructor(t){super("Failed to release ArtPlayer resources"),this.errors=t,this.name="ResourceCleanupError"}}class m{constructor(){this.cleanups=new Set,this.disposed=!1}get closed(){return this.disposed}add(t){let e=!0;const r=()=>{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new m,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof h?t.push(...e.errors):t.push(e)}if(t.length)throw new h(t)}}const g=new WeakMap,v=new WeakMap;function y(t){const e=g.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function b(t){return y(t).scope}function w(t){const e=y(t);return e.destroying||e.scope.closed}function x(t,e,r,n,o=!1){const i=y(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],s=t=>{try{t()}catch(e){a.push(...e instanceof h?e.errors:[e])}};n&&t.template?.$video&&s(()=>t.reset()),s(()=>i.scope.dispose()),s(()=>(t.template||i.mountingTemplate)?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),s(()=>t.emit("destroy")),s(()=>i.finalizers.dispose()),o&&i.rollback&&s(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const l of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",l);if(a.length)throw a[0]}const k=new WeakMap;function $(t,e){const r=b(t).child();return k.set(e,r),r}function E(t){const e=k.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function A(t){k.get(t)?.dispose()}function C(t,e,r,n){const o=E(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function S(t,e){return{on:(r,n)=>{C(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=E(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}function T(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode??null;return"undefined"===typeof window||e.includes(window)||e.push(window),e}function L(t,e){return T(t).includes(e)}function P(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function M(t){return t.getBoundingClientRect()}function z(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;";try{document.body.appendChild(t);const e=getComputedStyle(t);return{top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0}}finally{t.remove()}}function R(t,e=document){return e.querySelector(t)}function O(t,e){return t.classList.add(e)}function D(t,e){return t.classList.remove(e)}function I(t,e){return t.classList.contains(e)}function N(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function _(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function W(t,e){_(t).forEach(t=>D(t,e)),O(t,e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function V(t){return document.createElement(t)}function Y(t,e,r="top"){u||(t.setAttribute("aria-label",e),O(t,"hint--rounded"),O(t,`hint--${r}`))}function B(t="",e=""){const r=V("i");return O(r,"art-icon"),O(r,`art-icon-${t}`),N(r,e),r}function H(t,e,r){return t.style[e]=r,t}function j(t,e){for(const r in e)H(t,r,e[r]);return t}function q(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new m;let a=!1,s=()=>{};function c(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function l(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void l(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const c=new Image;d(c,()=>l(c)),i.closed||(c.src=e)}catch(e){c(e)}}))}),i.closed||(n.src=t)}catch(u){c(u)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){c(u)}},e.onerror=()=>c(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}class U extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function X(t,e){if(!t)throw new U(e);return t}function G(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function K(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function Z(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function J(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function Q(t){return t.charAt(0).toUpperCase()+t.slice(1)}function tt(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const et={"&":"&","<":"<",">":">","'":"'",'"':"""},rt={"&":"&","<":"<",">":">","'":"'",""":'"'},nt=/(&|<|>|'|")/g;function ot(t){return t.replace(/[&<>'"]/g,t=>et[t]||t)}const it=Object.defineProperty,{hasOwnProperty:at}=Object.prototype;function st(t,e){return at.call(t,e)}function ct(t,e){return Object.getOwnPropertyDescriptor(t,e)}function lt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?lt(o,i):i,it(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function dt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function ut(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function pt(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const ft=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:U,addClass:O,append:N,assToVtt:pt,capitalize:Q,clamp:J,createElement:V,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:it,download:Z,errorHandle:X,escape:ot,get:ct,getComposedPath:T,getExt:K,getIcon:B,getRect:M,getSafeAreaInsets:z,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:I,includeFromEvent:L,inverseClass:W,isBrowser:p,isIOS:l,isIOS13:d,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:u,isSafari:c,loadImg:function(t,e){return q(t,e,void 0)},mergeDeep:lt,query:R,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:D,replaceElement:F,secondToTime:tt,setStyle:H,setStyleText:a,setStyles:j,siblings:_,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:P,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:Y,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:s,vttToBlob:ut},Symbol.toStringTag,{value:"Module"}));function ht(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let c=()=>{};function l(e){a&&c(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,l,o),c=t.add(()=>{try{e.removeEventListener(r,l,i)}finally{s?.removeEventListener("abort",c)}}),s?.addEventListener("abort",c,{once:!0}),c}function mt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function gt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const vt=new WeakSet;function yt(t){vt.add(t),t.preventDefault()}function bt(t){return!t.altKey&&!t.ctrlKey&&!t.metaKey&&!t.isComposing&&229!==t.keyCode}function wt(t,e,r=()=>e.click(),n=()=>!0){if(t.closed)return;e.hasAttribute("role")||e.setAttribute("role","button"),e.hasAttribute("tabindex")||(e.tabIndex=0);let o=!1;const i=()=>n()&&"true"!==e.getAttribute("aria-disabled")&&!e.hasAttribute("disabled"),a=t=>(t.composedPath()[0]||t.target)===e;ht(t,e,"keydown",t=>{const e=t;a(e)&&bt(e)&&!e.defaultPrevented&&("Enter"===e.key?(yt(e),!e.repeat&&i()&&r()):" "===e.key&&(yt(e),!e.repeat&&i()&&(o=!0)))}),ht(t,e,"keyup",t=>{const n=t;if(" "!==n.key)return;const s=o;o=!1,s&&a(n)&&bt(n)&&!n.defaultPrevented&&i()&&e.ownerDocument.activeElement===e&&(yt(n),r())}),ht(t,e,"blur",()=>{o=!1}),t.add(()=>{o=!1})}function xt(t,e){return N(t,e)}function kt(t,e){return e.querySelector(t)}const $t=new WeakSet;function Et(t){const e=t.template.$player;!w(t)&&e.isConnected&&(e.hasAttribute("tabindex")||(e.setAttribute("tabindex","-1"),$t.has(e)||($t.add(e),b(t).add(()=>{$t.delete(e),"-1"===e.getAttribute("tabindex")&&e.removeAttribute("tabindex")}))),e.focus({preventScroll:!0}))}const At=new WeakSet,Ct="[tabindex],button,input,select,textarea,a[href],[contenteditable]";function St(t){return[t,...t.querySelectorAll(Ct)].find(t=>{if(!t.matches(Ct)||t.tabIndex<0||t.matches(":disabled")||t.closest("[inert]")||"true"===t.getAttribute("aria-disabled")||!t.getClientRects().length)return!1;const e=t.ownerDocument.defaultView?.getComputedStyle(t);return"hidden"!==e?.visibility&&"collapse"!==e?.visibility})}function Tt(t,e,r){const n=e?.ownerDocument,o=n?.activeElement;if(!["control","contextmenu"].includes(t.name??"")||At.has(t)||!e||!n||!o||!e.contains(o))return()=>{};const i=t.art.template.$player,a=Array.from(i.querySelectorAll(`.art-${t.name}`)),s=a.indexOf(e),c=[...a.slice(s+1),...a.slice(0,s).reverse()];return At.add(t),()=>{if(At.delete(t),w(t.art)||!i.isConnected||n.activeElement!==n.body)return;const e=r?t.cache.get(r)?.$ref:void 0;for(const t of[...e?[e]:[],...c]){if(!i.contains(t))continue;const e=St(t);if(e)return void e.focus({preventScroll:!0})}Et(t.art)}}const Lt="array",Pt="boolean",Mt="string",zt="number",Rt="object",Ot="function";function Dt(t,e,r){return X(e===Mt||e===zt||t instanceof Element,`${r.join(".")} require '${Mt}' or 'Element' type`)}const It={html:Dt,disable:`?${Pt}`,name:`?${Mt}`,index:`?${zt}`,style:`?${Rt}`,click:`?${Ot}`,mounted:`?${Ot}`,tooltip:`?${Mt}|${zt}`,width:`?${zt}`,selector:`?${Lt}`,onSelect:`?${Ot}`,switch:`?${Pt}`,onSwitch:`?${Ot}`,range:`?${Lt}`,onRange:`?${Ot}`,onChange:`?${Ot}`},Nt={id:Mt,container:Dt,url:Mt,poster:Mt,type:Mt,theme:Mt,lang:Mt,volume:zt,isLive:Pt,muted:Pt,autoplay:Pt,autoSize:Pt,autoMini:Pt,loop:Pt,flip:Pt,playbackRate:Pt,aspectRatio:Pt,screenshot:Pt,setting:Pt,hotkey:Pt,pip:Pt,mutex:Pt,backdrop:Pt,fullscreen:Pt,fullscreenWeb:Pt,subtitleOffset:Pt,miniProgressBar:Pt,useSSR:Pt,playsInline:Pt,lock:Pt,gesture:Pt,fastForward:Pt,autoPlayback:Pt,autoOrientation:Pt,airplay:Pt,proxy:`?${Ot}`,plugins:[Ot],layers:[It],contextmenu:[It],settings:[It],controls:[{...It,position:(t,e,r)=>{const n=["top","left","right"];return X("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${Pt}`,html:Mt,url:Mt}],highlight:[{time:zt,text:Mt}],thumbnails:{url:Mt,number:zt,column:zt,width:zt,height:zt,scale:zt},subtitle:{url:Mt,name:Mt,type:Mt,style:Rt,escape:Pt,encoding:Mt,onVttLoad:Ot},moreVideoAttr:Rt,i18n:Rt,icons:Rt,cssVar:Rt,customType:Rt},_t=new WeakSet;class Wt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return I(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?O(e,r):D(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(w(this.art))return;const e="function"===typeof t?t(this.art):t;if(w(this.art))return;if(e.html=e.html||"",o(e,It),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;X(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=$(this.art,i),s=[],c=Object.getOwnPropertyDescriptor(this,r);let l=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){O(t,`art-${r}`),O(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):N(e,t),i.html&&N(t,i.html),i.style&&j(t,i.style),i.tooltip&&Y(t,i.tooltip)}(i,this.$parent,this.name,r,this.id,e),a.closed)return;if(e.click){("control"===this.name&&!e.selector||"contextmenu"===this.name&&!i.querySelector("[data-value]"))&&!i.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")&&wt(a,i);const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,r,i),l=!0,n.set(r,{$ref:i,events:s,option:e}),e.mounted&&e.mounted.call(this.art,i),i}catch(d){try{A(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw n.get(r)?.$ref===i&&n.delete(r),l&&this[r]===i&&(c?Object.defineProperty(this,r,c):delete this[r]),i.remove(),d}}remove(t){X(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(_t.has(e))return;const r=Tt(this,e.$ref);_t.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{A(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{_t.delete(e),r()}}update(t){const e=Tt(this,this.cache.get(t.name)?.$ref,t.name);try{if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}finally{e()}}}function Ft(t){for(const e of t.querySelectorAll("[data-value]"))e.setAttribute("aria-pressed",String(e.classList.contains("art-current")))}function Vt(t,e){const r=E(t);if(!r.closed){t.setAttribute("role","group"),t.setAttribute("aria-label",e);for(const n of t.querySelectorAll("[data-value]"))wt(r,n),n.setAttribute("aria-label",`${e}: ${n.textContent?.trim()??""}`);Ft(t)}}const Yt=new WeakMap;function Bt(t,e){e?Yt.set(t,e):Yt.delete(t)}function Ht(t){const e=new Set;let r=t;for(;!e.has(r);){e.add(r);let t,n=r;for(;n&&!t;)t=Yt.get(n),n=n.parentElement;if(!t)return r;r=t}return t}function jt(t){const e=t;return!!e&&(["INPUT","TEXTAREA","SELECT"].includes(e.tagName)||e.isContentEditable)}function qt(t){const e=t.ownerDocument.defaultView?.getComputedStyle(t).visibility;return t.isConnected&&!t.matches(":disabled")&&!t.closest("[inert]")&&"true"!==t.getAttribute("aria-disabled")&&t.getClientRects().length>0&&"hidden"!==e&&"collapse"!==e}class Ut extends Wt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,$(t,this.$parent),u||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=S(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join(""),i=r.get("Play Speed");return{...t,html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=S(e,t),n=R('[data-value="1"]',t);n&&W(n,"art-current"),Vt(t,i),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&(W(r,"art-current"),Ft(t))})}}}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join(""),i=r.get("Aspect Ratio");return{...t,html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=S(e,t),n=R('[data-value="default"]',t);n&&W(n,"art-current"),Vt(t,i),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&(W(r,"art-current"),Ft(t))})}}}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(Q(t))}`).join(""),i=r.get("Video Flip");return{...t,html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=S(e,t),n=R('[data-value="normal"]',t);n&&W(n,"art-current"),Vt(t,i),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&(W(r,"art-current"),Ft(t))})}}}}({name:"flip",index:30})),this.add(function(t){return e=>({...t,html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return{...t,html:`ArtPlayer ${i}`}}({name:"version",index:50})),this.add(function(t){return e=>({...t,html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{this.show=!0,a.closed||w(this.art)||!this.show||function(t,e,r){const{$player:n,$contextmenu:o}=t.template,{height:i,width:a,left:s,top:c}=M(n),{height:l,width:d}=M(o);let u=e-s,p=r-c;e+d>s+a&&(u=a-d),r+l>c+i&&(p=i-l),w(t)||j(o,{top:`${p}px`,left:`${u}px`})}(this.art,t,e)},c=function(t,e){const{art:r}=t,{$player:n,$contextmenu:o}=r.template,i=E(o),a=()=>!i.closed&&!w(r);let s,c=!1,l="",d=0;const u=()=>{const t=n.ownerDocument.activeElement;s=t&&n.contains(t)?Ht(t):n,Bt(o,s)},p=()=>Array.from(o.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]")).filter(t=>t.tabIndex>=0&&qt(t)),f=r.i18n.get("Context Menu");if(!a())return{pointer:()=>!1};o.setAttribute("role","group"),o.setAttribute("aria-label",f);const h=t=>{if(!a())return;if(t)return void(o.contains(n.ownerDocument.activeElement)||u());const e=n.ownerDocument.activeElement,i=o.contains(e)||c&&e===n.ownerDocument.body,d=s;s=void 0,c=!1,l="",Bt(o),i&&(d&&n.contains(d)&&qt(d)&&d.focus({preventScroll:!0}),(n.ownerDocument.activeElement===n.ownerDocument.body||o.contains(n.ownerDocument.activeElement))&&Et(r))};r.on("contextmenu",h),i.add(()=>{r.off("contextmenu",h),Bt(o)}),ht(i,o,"focusin",()=>{c=!0});let m=!1;return ht(i,o,"focusout",e=>{o.contains(e.relatedTarget)||m||(m=!0,mt(i,()=>{m=!1,a()&&t.show&&!o.contains(n.ownerDocument.activeElement)&&(t.show=!1)},0))}),ht(i,n,"keydown",n=>{const i=n;if(!a()||!bt(i)||i.defaultPrevented)return;if(("ContextMenu"===i.key||"F10"===i.key&&i.shiftKey)&&r.constructor.CONTEXTMENU&&!jt(i.target)){yt(i),u();const r=i.target.getBoundingClientRect();return e(r.left,r.bottom),void(a()&&t.show&&p()[0]?.focus({preventScroll:!0}))}if(!t.show||!o.contains(i.target))return;if("Escape"===i.key)return yt(i),void(t.show=!1);if("Tab"===i.key)return void(t.show=!1);if(jt(i.target))return;const s=p(),c=s.indexOf(i.target);let f;if("ArrowDown"===i.key||"ArrowRight"===i.key)f=s[(c+1)%s.length];else if("ArrowUp"===i.key||"ArrowLeft"===i.key)f=s[(c+s.length-1)%s.length];else if("Home"===i.key)f=s[0];else if("End"===i.key)f=s[s.length-1];else{if(1!==i.key.length||" "===i.key)return;{const t=i.key.toLowerCase();l=Date.now()-d>700?t:l+t,d=Date.now();const e=[...l].every(e=>e===t)?t:l;f=[...s.slice(c+1),...s.slice(0,c+1)].find(t=>(t.getAttribute("aria-label")||t.textContent||"").trim().toLowerCase().startsWith(e))}}yt(i),f?.focus({preventScroll:!0})}),{pointer:t=>!(!a()||!r.constructor.CONTEXTMENU||jt(t.target))&&(u(),!0)}}(this,s);o(e,"contextmenu",t=>{c.pointer(t)&&(t.preventDefault(),s(t.clientX,t.clientY))}),o(e,"click",t=>{L(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}const Xt=new WeakMap,Gt=new WeakMap,Kt=new WeakMap;function Zt(t){return Kt.get(t)||b(t)}function Jt(t){const e=Xt.get(t),r=Kt.get(t);return()=>Xt.get(t)===e&&(!e||e.active())&&Kt.get(t)===r&&(!r||!r.closed)}function Qt(t){const e=Kt.get(t),r=b(t).child(),n=r.child();Kt.set(t,r),r.add(()=>{Kt.get(t)===r&&Kt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!w(t)&&!n.closed&&Xt.get(t)===o};return Xt.set(t,o),n.add(()=>{Xt.get(t)===o&&Xt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function te(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function ee(t,e,r){Gt.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Gt.get(t)===e&&(Gt.delete(t),te(e))}}function re(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function ne(t,e){const{$progress:r}=t.template,{left:n}=M(r),o=J((u?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:tt(i),width:o,percentage:J(o/r.clientWidth,0,1)}}function oe(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=ne(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}const ie=new Map([["ArrowRight",1],["ArrowUp",1],["ArrowLeft",-1],["ArrowDown",-1],["PageUp",10],["PageDown",-10]]);function ae(t,e,r,n,o,i="horizontal"){const a=t=>[t.min,t.max,t.value,t.step].every(Number.isFinite)&&t.max>t.min&&t.step>0,s=(t,e)=>Math.min(e.max,Math.max(e.min,t)),c=()=>{if(t.closed)return;const r=n(),o=a(r),i=o?s(r.value,r):0;e.setAttribute("aria-disabled",String(!o)),e.setAttribute("aria-valuemin",String(o?r.min:0)),e.setAttribute("aria-valuemax",String(o?r.max:0)),e.setAttribute("aria-valuenow",String(i)),e.setAttribute("aria-valuetext",r.text(i))};return t.closed||(e.setAttribute("role","slider"),e.tabIndex=0,e.setAttribute("aria-label",r),e.setAttribute("aria-orientation",i),ht(t,e,"keydown",t=>{const r=t;if((r.composedPath()[0]||r.target)!==e||!bt(r)||r.defaultPrevented)return;const i=ie.get(r.key);if(void 0===i&&"Home"!==r.key&&"End"!==r.key)return;yt(r);const l=n();if(!a(l))return void c();const d="Home"===r.key?l.min:"End"===r.key?l.max:s(l.value,l)+i*l.step;o(s(d,l)),c()}),c()),c}const se=new WeakMap;function ce(t){return se.get(t)||0}function le(t,e,r){let n,o=!1,i=!1,a=!1,s=ce(t);const c=()=>a||ce(t)!==s,l=()=>!!t.template?.$video?.seeking;return{restore(i=()=>{t.currentTime=e}){if(!r()||c())return;const d=ce(t);i(),s=ce(t),s>d+1&&(a=!0),r()&&(n=t.currentTime,r()&&!c()&&(o=l()))},manual(){a=!0},ready(){if(!r()||l())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!c()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!l()}}}function de(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=E(e),{on:a}=S(t,e);let s=()=>{};const c=kt(".art-progress-hover",e),l=kt(".art-progress-loaded",e),d=kt(".art-progress-played",e),p=kt(".art-progress-highlight",e),f=kt(".art-progress-indicator",e),h=kt(".art-progress-tip",e);function m(r,n){const{width:o,time:i}=n||ne(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?H(h,"left",0):o>e.clientWidth-a/2?H(h,"left",e.clientWidth-a+"px"):H(h,"left",o-a/2+"px")}r.indicator?N(f,r.indicator):H(f,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const g="played"===r&&a&&u;if("loaded"===r&&H(l,"width",100*n+"%"),"hover"===r&&(H(c,"width",100*n+"%"),L(a,p)?function(r){const{width:n}=ne(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const i=h.clientWidth;n<=i/2?H(h,"left",0):n>e.clientWidth-i/2?H(h,"left",e.clientWidth-i+"px"):H(h,"left",n-i/2+"px")}(a):m(a),0===n?D(o,"art-progress-hover"):O(o,"art-progress-hover")),"played"===r&&(H(d,"width",100*n+"%"),H(f,"left",100*n+"%")),g){O(o,"art-progress-hover");m(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=mt(i,()=>{D(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){p.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function ue(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{de(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=S(t,e),a=E(e);let s=0;const c=()=>{const e=Jt(t);return()=>!a.closed&&!w(t)&&e()},l=()=>{const t=++s,e=c();return()=>t===s&&e()};if(!u){let e;i(r,"click",e=>{e.target!==n&&oe(t,e,l())}),i(r,"mousemove",e=>{const r=c(),{percentage:n}=ne(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?l():void 0}),o("document:mousemove",r=>{const n=e;if(n?.()){const{second:o,percentage:i}=ne(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t),function(t,e){const r=E(e),{on:n}=S(t,e);let o,i=0;const a=ae(r,e,t.i18n.get("Progress"),()=>({min:0,max:t.duration,value:t.currentTime,step:t.constructor.SEEK_STEP,text:e=>`${tt(e)} / ${tt(Number.isFinite(t.duration)&&t.duration>0?t.duration:0)}`}),e=>{const n=++i;o?.dispose();const s=r.child();o=s;const c=Zt(t).add(()=>{s.dispose()});s.add(()=>{c()}),s.add(()=>{o===s&&(o=void 0)});const l=Jt(t),d=()=>n===i&&!s.closed&&!w(t)&&l(),u=le(t,e,d),p=()=>{d()?u.ready()&&(s.dispose(),a()):s.dispose()};for(const r of["video:seeked","video:ended"])t.on(r,p),s.add(()=>{t.off(r,p)});try{t.emit("setBar","played",e/t.duration),d()&&u.restore(()=>{t.seek=e}),p()}catch(f){throw s.dispose(),f}});n("video:loadedmetadata",a),n("video:durationchange",a),n("video:emptied",a),n("video:timeupdate",a),n("video:seeking",a),n("video:seeked",a),n("video:ended",a)}(e,t)}})}function pe(t){const{option:e}=t.art;e.isLive||t.add(ue({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e,a=xt(t,o.play),s=xt(t,o.pause);function c(){t.setAttribute("aria-label",i.get("Play")),H(a,"display","flex"),H(s,"display","none")}function l(){t.setAttribute("aria-label",i.get("Pause")),H(a,"display","none"),H(s,"display","flex")}wt(E(t),t,()=>(e.playing?s:a).click()),Y(a,i.get("Play")),Y(s,i.get("Pause")),n(a,"click",()=>{G(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?l():c(),r("video:playing",()=>{l()}),r("video:pause",()=>{c()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e,a=xt(t,o.volume),s=xt(t,o.volumeClose);for(const e of[a,s])wt(E(t),e),e.setAttribute("aria-label",i.get("Mute"));const c=xt(t,'
'),l=xt(c,'
'),d=xt(l,'
'),p=xt(l,'
'),f=xt(p,'
'),h=xt(f,'
'),m=xt(p,'
'),g=E(t);let v=0;const y=ae(g,p,i.get("Volume"),()=>({min:0,max:100,value:e.muted?0:100*e.volume,step:100*e.constructor.VOLUME_STEP,text:t=>`${Math.round(t)}%`}),t=>{const r=++v;e.muted=!1,r!==v||g.closed||w(e)||(e.volume=t/100)},"vertical");function b(t){const{top:e,height:r}=M(p);return 1-(t.clientY-e)/r}function x(){y();const r=t.ownerDocument.activeElement,n=e.muted||0===e.volume,o=n?s:a;if(a.setAttribute("aria-pressed",String(e.muted)),s.setAttribute("aria-pressed",String(e.muted)),n)H(a,"display","none"),H(s,"display","flex"),H(m,"top","100%"),H(h,"top","100%"),d.textContent="0";else{const t=100*e.volume;H(a,"display","flex"),H(s,"display","none"),H(m,"top",100-t+"%"),H(h,"top",100-t+"%"),d.textContent=String(Math.floor(t))}r!==a&&r!==s||r===o||o.focus({preventScroll:!0})}if(x(),r("video:volumechange",x),n(a,"click",()=>{e.muted=!0}),n(s,"click",()=>{e.muted=!1}),u)H(c,"display","none");else{let t=!1;n(p,"mousedown",r=>{t=0===r.button,e.volume=b(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=b(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>({...t,style:u?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=S(e,t);function n(){const r=`${tt(e.currentTime)} / ${tt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!b(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!u&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=S(e,t),{icons:n}=e;wt(E(t),t),xt(t,n.screenshot),r(t,"click",()=>{G(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e;xt(t,o.setting),wt(E(t),t),t.setAttribute("aria-expanded","false"),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{t.setAttribute("aria-expanded",String(e)),Y(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e;wt(E(t),t),xt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{Y(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=S(e,t),{icons:n}=e;wt(E(t),t),xt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e;wt(E(t),t);const a=xt(t,o.fullscreenWebOn),s=xt(t,o.fullscreenWebOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(Y(t,i.get("Exit Web Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(Y(t,i.get("Web Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e;wt(E(t),t);const a=xt(t,o.fullscreenOn),s=xt(t,o.fullscreenOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(Y(t,i.get("Exit Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(Y(t,i.get("Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rme.get(t).option.selector}),it(t,"$control_item",{get:()=>me.get(t).item}),it(t,"$control_value",{get:()=>me.get(t).value})),me.set(t,e)}function ve(t,e){t.innerHTML=e}function ye(t,e,r,n,o){const{proxy:i}=t.events,a=E(n),s=r.selector;O(n,"art-control-selector");const c=document.createElement("div");O(c,"art-selector-value"),N(c,r.html),n.textContent="",N(n,c);const l=xt(n,'
');for(let f=0;f{if(a.closed)return;const o=T(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++d,l=()=>!a.closed&&s===d,u=a.add(function(t,e){return fe.set(t,e),()=>{fe.get(t)===e&&fe.delete(t)}}(n,l));try{if(e(i),a.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,i,i.$control_item,n);if(l()){const t=c.contains(c.ownerDocument.activeElement);ve(c,e),me.get(i)?.refresh?.(t)}}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{u()}});o.push(u);const p=function(t,e,r,n,o){if(t.closed)return()=>{};const i=Array.from(n.children),a=i.some(t=>t.querySelector(he));n.setAttribute("role",a?"group":"listbox"),n.setAttribute("aria-label",o);let s=!1,c=!1,l=!1,d="",u=0;const p=()=>i.length>0&&(c||s&&!l),f=()=>r.querySelector('button,a[href],[role="button"]')||r,h=(e=!1)=>{if(t.closed)return;const n=f();r.querySelector(he)?(r.removeAttribute("role"),r.removeAttribute("tabindex")):(r.setAttribute("role","button"),r.tabIndex=0),n!==r&&(r.removeAttribute("aria-haspopup"),r.removeAttribute("aria-expanded"),r.removeAttribute("aria-disabled")),a?n.removeAttribute("aria-haspopup"):n.setAttribute("aria-haspopup","listbox"),n.setAttribute("aria-expanded",String(p())),n.setAttribute("aria-disabled",String(0===i.length)),e&&r.isConnected&&r.ownerDocument.activeElement===r.ownerDocument.body&&n.focus({preventScroll:!0})},m=(t,r=!1)=>{c=t,l=r,e.classList.toggle("art-selector-open",t),e.classList.toggle("art-selector-dismissed",r),h()},g=e=>{e&&!t.closed&&((e.querySelector(he)||e).focus({preventScroll:!0}),t.closed||e.scrollIntoView({block:"nearest",inline:"nearest"}))},v=(e=!1)=>{!t.closed&&i.length&&(m(!0),d="",g(i.find(t=>t.classList.contains("art-current"))||i[e?i.length-1:0]))},y=()=>{if(t.closed)return;const o=n.contains(e.ownerDocument.activeElement);m(!1,!0),d="",o&&r.isConnected&&f().focus({preventScroll:!0})};wt(t,r,()=>{r.click(),e.ownerDocument.activeElement===r&&v()}),h();for(const b of i){const e=b.classList.contains("art-current");a?b.setAttribute("aria-current",String(e)):(b.setAttribute("role","option"),b.setAttribute("aria-selected",String(e))),b.querySelector(he)||(b.tabIndex=-1,wt(t,b,()=>{b.click(),y()}))}return ht(t,r,"keydown",t=>{const e=t;!bt(e)||e.defaultPrevented||e.target!==r&&e.target!==f()||("ArrowDown"===e.key||"ArrowUp"===e.key?(yt(e),v("ArrowUp"===e.key)):"Escape"===e.key&&p()&&(yt(e),y()))}),ht(t,r,"click",t=>{t.isTrusted&&0===t.detail&&f()!==r&&v()}),ht(t,n,"keydown",t=>{const e=t;if(!bt(e)||e.defaultPrevented)return;if("Escape"===e.key)return yt(e),void y();const r=i.indexOf(e.target);if(r<0)return;let n;switch(1!==e.key.length&&(d=""),e.key){case"ArrowDown":n=Math.min(r+1,i.length-1);break;case"ArrowUp":n=Math.max(r-1,0);break;case"Home":n=0;break;case"End":n=i.length-1;break;case"ArrowLeft":case"ArrowRight":return void yt(e);default:{if(1!==e.key.length||" "===e.key)return;const t=Date.now();d=t-u<500?d+e.key.toLocaleLowerCase():e.key.toLocaleLowerCase(),u=t;const o=[...d].every(t=>t===d[0])?d[0]:d;for(let e=1;e<=i.length;e++){const t=(r+e)%i.length;if(i[t].textContent?.trim().toLocaleLowerCase().startsWith(o)){n=t;break}}}}yt(e),void 0!==n&&g(i[n])}),ht(t,n,"click",t=>{t.isTrusted&&0===t.detail&&y()}),ht(t,e,"mouseenter",()=>{s=!0,m(c)}),ht(t,e,"mouseleave",()=>{s=!1,m(n.contains(e.ownerDocument.activeElement))}),ht(t,e,"focusout",t=>{e.contains(t.relatedTarget)||m(!1,!0)}),t.add(()=>{e.classList.remove("art-selector-open","art-selector-dismissed")}),h}(a,n,c,l,String(r.tooltip||r.name||c.textContent||t.i18n.get("Open")));for(const f of s)me.get(f).refresh=p}class be extends Wt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template,o=function(t,e,r){let n,o,i=!0;const a=()=>!t.closed&&i&&e.contains(e.ownerDocument.activeElement),s=()=>{const t=a(),n=e.classList.contains("art-keyboard-focus");e.classList.toggle("art-keyboard-focus",t),t&&!n&&r()},c=()=>{i=!0,s()},l=()=>{i=!1,s()},d=()=>{n!==e.ownerDocument&&(o?.dispose(),n=e.ownerDocument,o=t.child(),ht(o,n,"keydown",c,{capture:!0}),ht(o,n,"mousedown",l,{capture:!0}),ht(o,n,"touchstart",l,{capture:!0,passive:!0}))};return d(),ht(t,e,"keydown",c,{capture:!0}),ht(t,e,"mousedown",l,{capture:!0}),ht(t,e,"touchstart",l,{capture:!0,passive:!0}),ht(t,e,"focusin",()=>{d(),s()}),ht(t,e,"focusout",()=>{e.classList.remove("art-keyboard-focus")}),t.add(()=>{e.classList.remove("art-keyboard-focus")}),a}($(t,n),r,()=>{this.show=!0}),{on:i,proxy:a}=S(t,n);a(r,"focusin",e=>{t.isFocus=!0,t.isInput="INPUT"===e.target?.tagName}),a(r,"focusout",e=>{r.contains(e.relatedTarget)||(t.isFocus=!1,t.isInput=!1)}),i("mousemove",()=>{u||(this.show=!0)}),i("click",()=>{u?this.toggle():this.show=!0}),i("document:mousemove",t=>{this.isHover=L(t,n)}),i("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&!o()&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),i("control",t=>{t?(D(r,"art-hide-cursor"),O(r,"art-hover"),this.timer=Date.now()):(O(r,"art-hide-cursor"),D(r,"art-hover"))}),this.init(),b(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=E(e),{on:i}=S(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){pe(this)}add(t){if(w(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:X(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(!t)return;const e=t.$control_value.contains(t.$control_value.ownerDocument.activeElement);ve(t.$control_value,t.html);for(let r=0;rthis.check(t),t,e,r)}}function we(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(w(t))return;const n=L(r,e);t.isInput=n&&"INPUT"===r.target?.tagName,t.isFocus=n,t.emit(n?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),b(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(w(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:c}=r,l=o.filter(t=>n-t<=a);switch(l.length){case 1:if(t.emit("click",e),w(t))return;(!u||!t.isLock&&i)&&G(t.toggle()),o=l;break;case 2:if(t.emit("dblclick",e),w(t))return;u?!t.isLock&&s&&G(t.toggle()):c&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function xe(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!w(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),b(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(w(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:Jt(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{oe(t,i,()=>n(s))}catch(c){throw e===s&&r(),c}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,c=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,c].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const l=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===l||2===l:3===l||4===l))return;const d=J((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=J(i.time+t.duration*d*c,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",J(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${tt(u)} / ${tt(t.duration)}`))},cancel:r}}const ke=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],$e=["resize","scroll","orientationchange"];const Ee=new WeakMap;function Ae(t){const e=Ee.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function Ce(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=Ce(t,e,r,n,o);return i.push(a),a})}catch(f){for(const t of i.reverse())try{t()}catch(h){console.warn("Failed to roll back event listener:",h)}throw f}}const i=r,a=Ae(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(o?.capture),once:Boolean(o?.once),passive:o?.passive,signal:o?.signal},c="boolean"===typeof s?s:s.capture,l="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||l?.aborted)return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,c),l?.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):l?.aborted?p():l?.addEventListener("abort",p,{once:!0})}catch(f){try{u(!0)}catch(h){console.warn("Failed to roll back event listener:",h)}throw f}return p}function Se(t){return(e,r)=>{if(w(t))return;const n=(...e)=>{if(!w(t))return r(...e)};t.on(e,n),b(t).add(()=>{t.off(e,n)})}}function Te(t){if(!t.constructor.USE_RAF)return;const e=b(t);let r=()=>{};const n=()=>{w(t)||(t.playing&&t.emit("raf"),w(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),Se(t)("destroy",()=>r())}class Le{constructor(t){this.destroyEvents=new Set,function(t,e){Ee.set(t,{scope:b(e),cleaning:!1})}(this,t),b(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),we(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{w(t)||(O(r,"art-hover"),t.emit("hover",!0,e))},e=>{w(t)||(D(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{w(t)||t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t,o=Se(t);o("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),w(t)||(t.aspectRatio=e,w(t)||(n.show=""))});const i=b(t);let a=()=>{};const s=()=>{w(t)||(a(),a=mt(i,()=>t.emit("resize"),n.RESIZE_TIME))};o("window:orientationchange",s),o("window:resize",s);const c=t.template.$player.ownerDocument.defaultView?.screen?.orientation;"function"===typeof c?.addEventListener&&e.proxy(c,"change",s)}(t,this),function(t,e){if(!u||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=xe(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=b(t),a=Se(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=o?.innerHeight||n.documentElement.clientHeight,a=o?.innerWidth||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,c=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&c}(n,r.SCROLL_GAP)),w(t)||(s=!0,mt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;b(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){if(w(t))return;const a=++n,s={disposers:[]},c=()=>a!==n||w(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,a=i.window||n.ownerDocument?.defaultView||window,l=(n,o,i)=>{for(const a of o){if(c())return;s.disposers.push(e.proxy(n,a,e=>{r!==s||w(t)||t.emit(`${i}:${a}`,e)}))}};l(o,ke,"document"),l(a,$e,"window")}catch(d){throw o(s),d}if(c())return void o(s);const l=r;r=s,o(l)}i(),e.bindGlobalEvents=i}(t,this),Te(t)}proxy(t,e,r,n={}){return Array.isArray(e),Ce(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=Ae(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function Pe(t){if(t&&1===t.nodeType)return t}function Me(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}function ze(t,e){if(function(t){return vt.has(t)}(t)||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const r=function(t,e){const r=t.target;return 9===r?.nodeType?r:r?.ownerDocument||t.view?.document||e}(t,e);let n=Pe(r.activeElement);for(;n?.shadowRoot?.activeElement;)n=Pe(n.shadowRoot.activeElement);if(n&&Me(n))return!1;const o=Pe(t.composedPath?.()[0])||Pe(t.target),i="Enter"===t.key||"Enter"===t.code||"NumpadEnter"===t.code;if(i||" "===t.key||"Space"===t.code){const t='button,summary,[role="button"],[role="switch"]'+(i?",a[href]":"");if(o?.closest?.(t)||n?.closest?.(t))return!1}return!o||!Me(o)}const Re=new WeakMap;class Oe{constructor(t){this.art=t,this.keys={},Re.set(this,{subscribed:!1}),u||this.init()}init(){const t=this.art;if(w(t))return;const e=Re.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{G(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!w(t)){if(t.isFocus&&ze(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const De={"Context Menu":"\u5feb\u6377\u83dc\u5355",Lock:"\u9501\u5b9a",Back:"\u8fd4\u56de",Settings:"\u8bbe\u7f6e",Progress:"\u64ad\u653e\u8fdb\u5ea6","Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",De);class Ie{constructor(t){this.art=t,this.languages={"zh-cn":De},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=st(this.languages,t)&&this.languages[t]||{}}get(t){return st(this.language,t)&&this.language[t]||t}update(t){this.languages=lt(this.languages,t),this.init()}}const Ne={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class _e{constructor(t){const e={...Ne,...t.option.icons};for(const r in e)it(this,r,{get:()=>B(r,e[r])})}}const We=new WeakMap;function Fe(t,e,r){const n=()=>!e.closed&&!w(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:c,$video:l}}=t,d=i(c,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)}),function(t,e,r){const{$player:n,$info:o,$infoClose:i}=t.template;if(!o)return;const a=()=>!e.closed&&!w(t),s=()=>n.classList.contains("art-info-show"),c=t.i18n.get("Close");if(!a())return;const l=t.i18n.get("Video Info");if(!a())return;i.setAttribute("aria-label",c),o.setAttribute("role","group"),o.setAttribute("aria-label",l),wt(e,i,()=>i.click(),s),ht(e,o,"keydown",t=>{const e=t;a()&&s()&&bt(e)&&!e.defaultPrevented&&"Escape"===e.key&&(yt(e),r())});const d=e=>{if(!a())return;const r=n.ownerDocument,s=r.activeElement;if(e)o.contains(s)||(We.delete(t),s&&n.contains(s)&&(We.set(t,Ht(s)),n.classList.contains("art-keyboard-focus")&&i.focus({preventScroll:!0})));else{const e=We.get(t);if(We.delete(t),!o.contains(s))return;const i=e&&r.defaultView?.getComputedStyle(e).visibility;e?.isConnected&&n.contains(e)&&e.getClientRects().length&&"hidden"!==i&&"collapse"!==i&&!e.matches(":disabled")&&!e.closest("[inert]")&&"true"!==e.getAttribute("aria-disabled")?e.focus({preventScroll:!0}):Et(t)}};t.on("info",d),e.add(()=>{t.off("info",d)})}(t,e,r);const f=()=>{try{for(const t of u){if(!n())return;const e=Reflect.get(l,t.dataset.video??"undefined");if(!n())return;const r="number"===typeof e?e.toFixed(2):e;if(!n())return;if(t.textContent!==r){const e=null==r?null:`${r}`;if(!n())return;t.textContent=e}}n()&&mt(e,f,a.INFO_LOOP_TIME)}catch(t){o(t)}};n()&&f()}catch(i){o(i)}}const Ve=new WeakMap;class Ye extends Wt{constructor(t){super(t),this.name="info",Ve.set(this,{revision:0}),u||this.init()}init(){const t=Ve.get(this),e=++t.revision;if(t.scope?.dispose(),w(this.art)||t.revision!==e)return;const r=b(this.art).child();t.scope=r,r.add(()=>{t.scope===r&&(t.scope=void 0)}),Fe(this.art,r,()=>{this.show=!1})}}class Be extends Wt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{H(i,"display","none"),H(s,"display",null),w(t)&&(c=!0)};var d;t.on("destroy",l),(d=t,y(d).finalizers).add(()=>{try{c||l()}finally{t.off("destroy",l)}}),w(t)||n.proxy(e.$state,"click",()=>{w(t)||G(t.play())})}}const qe=new WeakMap;function Ue(t){const e=qe.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class Xe{constructor(t){this.art=t,this.timer=null,qe.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),b(t).add(()=>{t.off("destroy",e)}),b(t).add(()=>{this.destroy()})}destroy(){Ue(this)}set show(t){if(w(this.art))return;const e=qe.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){Ue(this);const i=e.revision,a=()=>!w(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(O(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const c={};e.pending=c;const l=setTimeout(()=>{if(w(this.art)||e.pending!==c)return;e.pending=void 0;const t=e.revision;o.textContent="",w(this.art)||e.revision!==t||D(n,"art-notice-show")},s);a()?this.timer=l:clearTimeout(l)}else D(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function Ge(t,e){return function(t,e){const r=lt(e,t);return r.container=t.container,o(r,Nt)}(t,e)}function Ke({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ze(t,e){if(!Ke(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Ke(r)?r:void 0}function Je(t,e,r,n=!1){const o=e=>{w(t)||r(e)};t[n?"once":"on"](e,o),b(t).add(()=>{t.off(e,o)})}function Qe(t,e,r){for(const[n,o]of e){if(w(t)||r&&!r())return;t[n].show=o}}function tr(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=Zt(t),c=0;return{reset(){c=0,a?.dispose(),D(i,"art-error")},loadStart(){D(i,"art-error")},schedule(l){(async l=>{if(w(t))return;const d=Zt(t);if(d!==s&&(s=d,c=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!w(t)&&!u.closed&&d===Zt(t),f=c{console.warn("ArtPlayer reconnect failed:",t)})}}}const er=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],rr=(()=>{if("undefined"===typeof document)return!1;const t=er[0],e={};for(const r of er){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),nr={change:rr.fullscreenchange,error:rr.fullscreenerror},or={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{or.off("change",o),r()};or.on("change",o);const i=t[rr.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!or.isFullscreen)return void t();const r=()=>{or.off("change",r),t()};or.on("change",r);const n=document[rr.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>or.isFullscreen?or.exit():or.request(t,e),onchange(t){or.on("change",t)},onerror(t){or.on("error",t)},on(t,e){const r=nr[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=nr[t];r&&document.removeEventListener(r,e,!1)},raw:rr};function ir(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(or,{isFullscreen:{get:()=>Boolean(document[rr.fullscreenElement])},element:{enumerable:!0,get:()=>document[rr.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[rr.fullscreenEnabled])}});const ar=new WeakMap;function sr(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function cr(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=ar.get(t);if(!n){n=new WeakMap,ar.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),sr(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),sr(i))}function lr(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,c=!1,l=!1,d=!1,u=!1,p=!1;const f=new Promise((t,e)=>{a=t,s=e});function h(t=!1,e){if(!c){c=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{c||(c=!0,l=!0,a(),d&&!u&&r&&cr(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&h()};if(ht(i,t.document,t.changeEvent,m),ht(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&h(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){ar.get(t.document)?.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,l&&!u&&r&&cr(t),u?Promise.resolve(e).then(()=>{l?n():h()},t=>h(!0,t)).catch(()=>{}):p?h(!0,new Error("Fullscreen request failed")):m()}catch(g){h(!0,g)}return{promise:f,cancel:()=>i.dispose()}}function dr(t,e){const r=b(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),c=0,l=s,d=!1,u=!1,p=!1;function f(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{c+=1,l=!1,n.classList.remove("art-fullscreen"),f()}),ht(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return ar.get(t.document)?.has(t.target)??!1}(e))return;if(r&&u)return void f();if(r===s||w(t))return;s=r;const o=c,a=()=>w(t)||i()!==r||o!==c&&l!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),ht(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!w(t)&&t.emit("fullscreenError",r)}),{get:()=>!w(t)&&i(),set(n){if(w(t))return Promise.resolve();const o=++c;if(l=Boolean(n),l?u=!1:d&&(u=!0),a?.cancel(),a=void 0,d=!1,!l&&!i())return Promise.resolve();p=!0,d=l;const s=lr(e,r,l,()=>{!w(t)&&l||f()},()=>!i());p=!1,c===o?a=s:s.cancel();const h=s.promise.catch(e=>{throw w(t)||c!==o||(t.notice.show=e),e}).finally(()=>{c===o&&(a=void 0,d=!1)});return h.catch(()=>{}),h}}}const ur=new WeakSet;function pr(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function fr(t){ur.delete(t),t.removeEventListener("webkitbeginfullscreen",hr),t.removeEventListener("webkitpresentationmodechanged",hr)}function hr(t){if(ur.has(this)&&pr(this,"webkitbeginfullscreen"===t.type)){fr(this);try{this.webkitExitFullscreen?.()}catch{}}}function mr(t){ur.add(t),t.addEventListener("webkitbeginfullscreen",hr),t.addEventListener("webkitpresentationmodechanged",hr)}function gr(t){const{$video:e}=t.template,r=b(t).child();let n=!1,o=pr(e),i=o,a=!1,s=0;const c=()=>pr(e,n);function l(r){if(w(t)||(l=e,ur.has(l)))return;var l;"boolean"===typeof r&&(n=r);const d=c();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>w(t)||c()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{s++,i=!1,a&&mr(e),c()&&e.webkitExitFullscreen?.()}),ht(r,e,"webkitbeginfullscreen",()=>l(!0)),ht(r,e,"webkitendfullscreen",()=>l(!1)),ht(r,e,"webkitpresentationmodechanged",()=>l());const d=()=>l();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!w(t)&&c(),set(r){if(w(t))return;const n=++s;if(i=Boolean(r),r){if(fr(e),t.state="fullscreen",w(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,mr(e)),c()&&e.webkitExitFullscreen()}}}function vr(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function yr({node:t,parent:e,next:r}){if(!e)return void t.parentNode?.removeChild(t);const n=r?.parentNode===e?r:null;t.parentNode===e&&t.nextSibling===n||e.insertBefore(t,n)}function br(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function wr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function xr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const c=t.icons.play,l=t.icons.pause;if(o.closed)return;i.append(c,l),s.append(e,i),wt(o,e,()=>e.click(),r),wt(o,i,()=>(t.playing?l:c).click(),r);const d=t.i18n.get("Close");if(o.closed||w(t))return;e.setAttribute("aria-label",d);const u=t.i18n.get("Mini Player");if(o.closed||w(t))return;s.setAttribute("role","group"),s.setAttribute("aria-label",u),ht(o,s,"keydown",t=>{const e=t;r()&&bt(e)&&!e.defaultPrevented&&"Escape"===e.key&&(yt(e),n())}),ht(o,e,"click",n),ht(o,c,"click",()=>{G(t.play())}),ht(o,l,"click",()=>{t.pause()});const p=()=>{if(o.closed)return;const e=t.i18n.get(t.playing?"Pause":"Play");o.closed||w(t)||(i.setAttribute("aria-label",e),c.style.display=t.playing?"none":"flex",l.style.display=t.playing?"flex":"none")};p();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,p),o.add(()=>{t.off(r,p)});const f=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};ht(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const c=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},l=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=br(i.left,i.top,wr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",c),r.add(()=>{t.off("document:mousemove",c)}),t.on("document:mouseup",l),r.add(()=>{t.off("document:mouseup",l)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:f,fresh:!0,focus:()=>e.focus({preventScroll:!0})}}catch(c){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,c}}function kr(t){const{$player:e,$video:r}=t.template,n=b(t).child();let o,i,a=0,s=!1,c=!1;const l=()=>!w(t)&&e.classList.contains("art-mini"),d=function(t){const e=t.template.$player;let r;return{entering(){const n=e.ownerDocument,o=n.activeElement,i=o&&e.contains(o);t.template.$mini?.contains(o)||(r=i?Ht(o):void 0);const a=i&&e.classList.contains("art-keyboard-focus");return e=>{!a||w(t)||n.activeElement!==o&&n.activeElement!==n.body||e?.()}},leaving(n){const o=e.ownerDocument,i=n?.contains(o.activeElement);return()=>{if(!i||w(t)||o.activeElement!==o.body&&!n?.contains(o.activeElement))return;const e=r&&o.defaultView?.getComputedStyle(r).visibility;r?.isConnected&&r.getClientRects().length&&"hidden"!==e&&"collapse"!==e&&"true"!==r.getAttribute("aria-disabled")&&!r.matches(":disabled")&&!r.closest("[inert]")?r.focus({preventScroll:!0}):Et(t)}}}}(t);function u(){if(i){const e=i,r=a;i=void 0;try{yr(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(w(t))return;const r=++a;c=!1;const n=d.leaving(t.template.$mini);u(),w(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",n(),w(t)||r!==a||t.emit("mini",!1)))}function f(){if(w(t))return;const h=++a;if(s)return void(c=!0);const m=d.entering();if(t.state="mini",!w(t)&&h===a){i??(i=vr(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=xr(t,n,l,p)}finally{s=!1}}if(c)return c=!1,void f();if(!o||w(t))return;if(h!==a)return void(l()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),w(t)||h!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:{...br(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,wr(o.element));if(w(t)||h!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),w(t)||h!==a)return;t.storage.set("left",i.left)}w(t)||h!==a||m(o.focus),w(t)||h!==a||t.emit("mini",!0)}catch(g){const r=c;throw c=!1,w(t)||h!==a&&!r||(u(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),g}}}return n.add(()=>{a++;try{u()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:l,set(t){t?f():p()}}}const $r=new WeakSet,Er=t=>"picture-in-picture"===t.webkitPresentationMode;function Ar(t){$r.delete(t),t.removeEventListener("webkitpresentationmodechanged",Cr),t.removeEventListener("enterpictureinpicture",Cr)}function Cr(){if($r.has(this)&&Er(this)){Ar(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function Sr(t){$r.add(t),t.addEventListener("webkitpresentationmodechanged",Cr),t.addEventListener("enterpictureinpicture",Cr)}function Tr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function Lr(t,e,r){return new Promise((n,o)=>{if(w(t)||e===t.url)return void n();const i=Qt(t),a=i.scope.child();let s=!1;const c=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{c()});const l=()=>!s&&i.active(),d=t=>c(!0,t);i.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!l())return;const u=a.child();let p=!1,f=!1,h=!1;const m=le(t,r,l),g=async()=>{if(t.aspectRatio=o,l()){if(n)try{await t.play()}catch{}l()&&(t.notice.show="",c())}},v=()=>{if(l()&&!f&&p)try{if(t.template?.$video?.seeking)return;if(!l())return;if(h||(h=!0,t.playbackRate=s),!m.ready()||!l()||f)return;f=!0,u.dispose(),g().catch(d)}catch(e){d(e)}},y={"video:error":d,"video:loadedmetadata":()=>{if(l())try{m.restore()}catch(t){d(t)}},"video:canplay":()=>{p=!0,v()},"video:seeked":v,seek:m.manual},b=a.child(),w=[],x=Object.keys(y);for(const e of x)Tr(b,t,e,t=>{i.acceptingEvents&&w.push([e,t])},!1);if(ee(t,i,e),!l())return;if(t.notice.show="",!l())return;const k=()=>{if(b.dispose(),!e)return void c();const r={};for(const e of x)r[e]=Tr(u,t,e,y[e],"video:seeked"!==e);for(const[t,e]of w){if(!l()||u.closed)break;r[t](e)}w.length=0};i.assigned?k():i.onAssigned=k}catch(u){d(u)}})}function Pr(t,e){const{number:r,column:n,width:o,height:i,scale:a}=t,{imageWidth:s,videoWidth:c,videoHeight:l,progressWidth:d,position:u}=e,p=Number(n),f=Number(o)*Number(a)||s/p,h=Number(i)*Number(a)||f/(c/l),m=Math.floor(u/(d/Number(r)));return{height:`${h}px`,width:`${f}px`,backgroundPosition:`-${m%p*f}px -${Math.floor(m/p)*h}px`,left:u<=f/2?0:u>d-f/2?d-f+"px":u-f/2+"px"}}function Mr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(w(t))return;const o=function(t){const e=Gt.get(t);return Gt.delete(t),e||Qt(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await gt(o.scope)&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||K(n),s=e.customType[a];if(a&&s){if(!(await gt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const c=o.scope.child();let l=!1,d=!1;Tr(c,t,"video:canplay",()=>{l=!d}),Tr(c,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>re(o,t))}else{if(!o.active())return;r.src=n}}finally{c.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};l?e():d||Tr(o.scope,t,"video:canplay",e)}}catch(i){re(o,i)}finally{te(o)}}})}const zr=[function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){const n=e;if(void 0===r)return n[t];n[t]=r}})},function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=Jt(t),s=await i.play();if(!a())return s;const c=e.get("Play");if(!a())return s;if(r.show=c,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})},function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${tt(t.currentTime)} / ${tt(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;it(t,"forward",{set(e){r.seek=t.currentTime+e}}),it(t,"backward",{set(e){r.seek=t.currentTime-e}})},function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=J(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),it(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})},function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){se.set(t,ce(t)+1)}(t),e.currentTime=J(n,0,t.duration))}})},function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})},function(t){const e=e=>Lr(t,e,0);it(t,"switchQuality",{value:e=>Lr(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})},function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;it(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!w(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ze({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(w(t))return;"width"===r?.axis?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,w(t)||t.emit("aspectRatio",i)}}})},function(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=Jt(t);return new Promise((a,s)=>{const c=r=>{try{!w(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,c):a(n.toDataURL("image/png"))}catch(l){c(l)}})}it(t,"getDataURL",{value:()=>o(!1)}),it(t,"getBlobUrl",{value:()=>o(!0)}),it(t,"screenshot",{value:async e=>{const n=Jt(t),o=await t.getDataURL();if(!w(t)&&n()){const i=e||`artplayer_${tt(r.currentTime)}`;!w(t)&&n()&&Z(o,`${i}.png`),!w(t)&&n()&&t.emit("screenshot",o)}return o}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(w(t))return;const i=function(t){const e=or.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>ir(t,e.requestFullscreen,void 0),exit:()=>ir(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",dr(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",gr(t)):it(t,"fullscreen",{get:()=>!1,set(){w(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",ct(t,"fullscreen"))};t.once("video:loadedmetadata",i),b(t).add(()=>{t.off("video:loadedmetadata",i)})},function(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(yr(t.placement),r()))}return b(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(i){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(a){throw new h([i,a])}throw i}}),i=>{if(w(t))return;const a=++n,s=()=>a===n&&!w(t),c=function(t){const e=t.ownerDocument?.activeElement,r=e&&t.contains(e);return()=>{r&&e.isConnected&&t.contains(e)&&e.ownerDocument.activeElement===e.ownerDocument.body&&e.focus({preventScroll:!0})}}(e);if(i){r||(r={placement:vr(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0,c()),l}if(!s())return;if(c(),!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;if(c(),!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);it(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})},function(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?it(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=b(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,c=!1,l=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function u(e,r,n){e.then(()=>{!r||!w(t)&&a||d()},e=>{w(t)||l!==n||(t.notice.show=e)}).finally(()=>{l===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{l++,a=!1,d()}),ht(n,e,"enterpictureinpicture",()=>{if(c)return void d();if(!o()||i)return;const e=l;t.state="pip",!w(t)&&e===l&&o()&&(i=!0,t.emit("pip",!0))}),ht(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!w(t)&&o()?e:null,set(n){if(w(t))return;const i=++l;if(a=Boolean(n),a?c=!1:s&&(c=!0),s=!1,a){if(t.state="pip",w(t)||l!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw l===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=b(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(w(t)||$r.has(e))return;const s=Er(e);if(s&&(o=!1),s===n&&!r)return;const c=i;s&&(t.state="pip"),w(t)||i!==c||Er(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&Sr(e),Er(e)&&e.webkitSetPresentationMode("inline")});for(const c of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])ht(r,e,c,()=>s());return{get:()=>!w(t)&&Er(e),set(r){if(w(t))return;const n=++i,c=a;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(Ar(e),t.state="pip",w(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(l){throw n===i&&(o=!1),l}}else o&&(o=!1,Sr(e)),Er(e)&&e.webkitSetPresentationMode("inline");w(t)||n!==i||c!==a||Er(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){w(t)||(r.show=e.get("PIP Not Supported"))}})},function(t){const{$video:e}=t.template,r=t;it(t,"loaded",{get:()=>r.loadedTime/e.duration}),it(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})},function(t){it(t,"played",{get:()=>t.currentTime/t.duration})},function(t){const{$video:e}=t.template;it(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})},function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(w(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Ke(o))return;const i=M(e),a=Ze(i,o.width/o.height);a&&!w(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})},function(t){const e=t;it(t,"rect",{get:()=>M(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}it(t,"x",{get:()=>e.left+window.pageXOffset}),it(t,"y",{get:()=>e.top+window.pageYOffset})},function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){w(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,w(t)||t.emit("flip",o))}})},function(t){it(t,"mini",kr(t))},function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){H(e,"backgroundImage",`url(${t})`)}})},function(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(w(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Ke(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||w(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})},function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})},function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})},function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})},function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];it(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;nn.$track?.offset||0,set(o){const{cues:i}=t.subtitle;if(!n.$track||0===i.length)return;const a=J(o,-10,10);n.$track.offset=a;for(let e=0;e{if(!w(t))switch(e.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,w(t)||it(t,"airplay",{value(){if(!w(t))if(i){const e=o.webkitShowPlaybackTargetPicker;if(w(t))return;Reflect.apply(e,o,[]),w(t)||t.emit("airplay")}else{const n=e.get("AirPlay Not Available");w(t)||(r.show=n)}}}))},function(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:i?.html||"",selector:e,async onSelect(e,r,i){const a=function(t){return t&&fe.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!w(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!w(t)&&a()&&(n.show=r)}return e.html}})}})},function(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,s=b(t).child(),c=!1;function l(){const e=s;s=b(t).child(),o=void 0,c=!1,a=void 0,e.dispose()}function d(){const i=a,c=s;if(!i||!o)return;const l=()=>!w(t)&&!c.closed&&s===c&&a===i&&i.sourceActive()&&t.controls?.thumbnails===i.element;if(!l())return;const d=r.clientWidth*i.percentage;if(!(d>0&&d{const f=t.controls?.thumbnails,{url:h,scale:m}=e.thumbnails;if(!w(t)&&f&&h&&("hover"===r||"played"===r&&p&&u)){if(i!==f){const t=E(f);if(t.closed)return;i=f,t.add(()=>{i===f&&(i=void 0,l())})}if(a={percentage:n,element:f,sourceActive:Jt(t)},o)d();else if(!c){const t=s;c=!0,function(t,e,r){return q(t,e,r)}(h,m,t).then(e=>{s!==t||t.closed||(c=!1,o=e,d())}).catch(e=>{s!==t||t.closed||(c=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{w(t)||!e.url||t.option.isLive||w(t)||(t.option.thumbnails=e,l())}})},function(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{w(t)||t.emit(`video:${e.type}`,e)})}(t);const e=tr(t);!function(t,e){Je(t,"video:canplay",()=>{e.reset(),Qe(t,[["loading",!1]])}),Je(t,"video:canplay",()=>{Qe(t,[["loading",!1],["controls",!0],["mask",!0]]),w(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Je(t,"video:ended",()=>{if(e.loop){const e=Jt(t);if(t.seek=0,w(t)||!e())return;G(t.play()),e()&&Qe(t,[["controls",!1],["mask",!1]],e)}else Qe(t,[["controls",!0],["mask",!0]])})}(t),Je(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Je(t,"video:loadedmetadata",()=>{t.emit("resize"),u&&Qe(t,[["loading",!1],["controls",!0],["mask",!0]])}),Je(t,"video:loadstart",()=>{e.loadStart(),Qe(t,[["loading",!0],["mask",!1],["controls",!0]])}),Je(t,"video:pause",()=>{Qe(t,[["controls",!0],["mask",!0]])}),Je(t,"video:play",()=>{Qe(t,[["mask",!1]]),w(t)||H(r,"display","none")}),Je(t,"video:playing",()=>Qe(t,[["mask",!1]])),Je(t,"video:progress",()=>{t.playing&&Qe(t,[["loading",!1]])}),Je(t,"video:seeked",()=>Qe(t,[["loading",!1],["mask",!0]])),Je(t,"video:seeking",()=>Qe(t,[["loading",!0],["mask",!1]])),Je(t,"video:timeupdate",()=>Qe(t,[["mask",!1]])),Je(t,"video:waiting",()=>Qe(t,[["loading",!0],["mask",!1]]))}(t,e)},function(t){if(w(t))return;const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const s in e.moreVideoAttr){if(w(t))return;const r=e.moreVideoAttr[s];if(w(t))return;t.attr(s,r)}if(w(t))return;if(e.muted){const r=e.muted;if(w(t))return;t.muted=r}if(w(t))return;if(e.volume){const r=J(e.volume,0,1);if(w(t))return;n.volume=r}if(w(t))return;const i=r.get("volume");if(w(t))return;if("number"===typeof i&&(n.volume=J(i,0,1)),w(t))return;if(e.poster){const r=`url(${e.poster})`;if(w(t))return;H(o,"backgroundImage",r)}if(w(t))return;if(e.autoplay){const r=e.autoplay;if(w(t))return;n.autoplay=r}if(w(t))return;if(e.playsInline){if(w(t))return;if(n.playsInline=!0,w(t))return;n["webkit-playsinline"]=!0}if(w(t))return;if(e.theme){const r=e.cssVar,n=e.theme;if(w(t))return;r["--art-theme"]=n}for(const s in e.cssVar){if(w(t))return;const r=e.cssVar[s];if(w(t))return;t.cssVar(s,r)}if(w(t))return;const a=e.url;w(t)||(t.url=a)}];class Rr{constructor(t){if(!w(t)){Mr(t);for(const e of zr){if(w(t))return;e(t)}}}}const Or=new WeakMap,Dr="art-auto-orientation-fullscreen";function Ir(t){if(Or.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const Nr="art-auto-orientation",_r=["width","height","transform-origin","transform"];function Wr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Ke(t)&&Ke(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=b(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(Nr);r.classList.remove(Nr),n&&(t.isRotate=!1,w(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=z();if(w(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=_r.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(Nr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{w(t)||(r?o?s(!1):e()&&(i(),i=mt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(Dr),t&&(t.cancelled=!0,Ir(t),t.settled&&Or.get(t.orientation)===t&&Or.delete(t.orientation))}return b(t).add(o),i=>{if(w(t))return;if(!i)return void o();if(n&&!n.cancelled&&Or.get(n.orientation)===n)return;const a=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof a?.lock||"function"!==typeof a.unlock||!e())return;const s={orientation:a,cancelled:!1,settled:!1};n=s,Or.set(a,s);const c=()=>!w(t)&&!s.cancelled&&n===s&&Or.get(a)===s,l=e=>{s.settled=!0;const o=c();Or.get(a)===s&&Or.delete(a),n===s&&(n=void 0),o&&(r.classList.remove(Dr),t.notice.show=e)};try{const t=a.lock(a.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,c()?r.classList.add(Dr):(Ir(s),Or.get(a)===s&&Or.delete(a))}).catch(l)}catch(d){l(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),b(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Fr(t){return t.get("times")||{}}function Vr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||w(t))return()=>{};const s=kt(".art-auto-playback-last",a),c=kt(".art-auto-playback-jump",a),l=kt(".art-auto-playback-close",a);xt(l,r.close);const d=E(a);let u,p=0;const f=()=>{const r=++p;if(u?.dispose(),d.closed||w(t)||p!==r)return;const f=d.child();u=f;const h=()=>u===f&&!f.closed&&!w(t);f.add(()=>{u===f&&(u=void 0,H(a,"display","none"))});const m=Zt(t).add(()=>{f.dispose()});f.add(()=>{m()});const g=Fr(n)[t.option.id||t.option.url];if(!h())return;if(H(a,"display","none"),!h()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!h())return;if(H(a,"display","flex"),!h())return;const v=`${e.get("Last Seen")} ${tt(g)}`;if(!h())return;if(s.textContent=v,!h())return;const y=e.get("Jump Play");if(!h())return;if(c.textContent=y,!h())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{h()&&r()});f.add(()=>{t.events.remove(n)})};if(b(l,()=>{H(a,"display","none")}),!h())return;if(b(c,()=>{t.seek=g,h()&&(G(t.play()),h()&&(H(i,"display","none"),h()&&H(a,"display","none")))}),!h())return;let x=()=>{},k=!1;const $=()=>{!k&&h()&&(k=!0,x(),mt(f,()=>{h()&&H(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",$),x=f.add(()=>{t.off("video:timeupdate",$)}),k&&x()};return()=>{C(t,a,"ready",f),C(t,a,"restart",f)}}(t);return function(t){const{storage:e,constructor:r}=t;Se(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Fr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;w(t)||(o.length>i&&delete n[o[0]],n[a]=s,w(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Fr(e)},clear:()=>e.del("times"),delete(t){const r=Fr(e);return delete r[t],e.set("times",r),r}}}function Yr(t){let e,r=0;return{start:n=>{const o=++r;if(e?.scope.dispose(),o!==r||w(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:Zt(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{e?.active||D(t.template.$player,"art-fast-forward")}}),mt(i.scope,()=>{if(e!==i||w(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||w(t))return;t.playbackRate=r,e!==i||i.scope.closed||w(t)||O(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,e?.scope.dispose()}}}function Br(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Yr(t),i=Se(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return I(r,"art-fast-forward")}}}function Hr(t,e,r,n){let o;const i=()=>!r.closed&&!w(t),a=t.i18n.get("Lock");if(!i())return()=>{};e.setAttribute("aria-label",a),wt(r,e),ht(r,e,"keydown",t=>{const r=t;i()&&n()&&bt(r)&&!r.defaultPrevented&&"Escape"===r.key&&(yt(r),e.click())});const s=n=>{if(i())if(e.setAttribute("aria-pressed",String(n)),n&&!o){const{$player:n,$bottom:a}=t.template,s=a.contains(a.ownerDocument.activeElement)&&n.classList.contains("art-keyboard-focus");o=r.child(),function(t,e){const r=new Map,n=e.hasAttribute("inert"),o=e.getAttribute("aria-hidden"),i=(t,e)=>{"-1"===t.getAttribute("tabindex")&&(null===e?t.removeAttribute("tabindex"):t.setAttribute("tabindex",e))};if(t.add(()=>{for(const[t,e]of r)i(t,e);r.clear(),n||""!==e.getAttribute("inert")||e.removeAttribute("inert"),"true"===e.getAttribute("aria-hidden")&&(null===o?e.removeAttribute("aria-hidden"):e.setAttribute("aria-hidden",o))}),t.closed)return;n||e.setAttribute("inert",""),e.setAttribute("aria-hidden","true");const a=()=>{if(!t.closed){for(const[t,n]of r)e.contains(t)||(i(t,n),r.delete(t));for(const t of e.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]"))r.has(t)||(r.set(t,t.getAttribute("tabindex")),t.setAttribute("tabindex","-1"))}};if(a(),"undefined"!==typeof MutationObserver){const r=new MutationObserver(a);r.observe(e,{childList:!0,subtree:!0}),t.add(()=>{r.disconnect()})}}(o,a),i()&&s&&e.focus({preventScroll:!0})}else if(!n&&o){const t=o;o=void 0,t.dispose()}};return s(n()),s}function jr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return I(n,"art-lock")}function i(){w(t)||(O(n,"art-lock"),w(t)||(t.isLock=!0,w(t)||t.emit("lock",!0)))}function a(){w(t)||(D(n,"art-lock"),w(t)||(t.isLock=!1,w(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=E(e);if(n.closed||w(t))return;const i=xt(e,r.lock);if(n.closed||w(t))return;const a=xt(e,r.unlock);if(n.closed||w(t))return;const s=Hr(t,e,n,o);n.closed||w(t)||(o()?(H(i,"display","inline-flex"),n.closed||w(t)||H(a,"display","none")):H(i,"display","none"),C(t,e,"lock",e=>{w(t)||(H(i,"display",e?"inline-flex":"none"),n.closed||w(t)||H(a,"display",e?"none":"inline-flex"),n.closed||w(t)||s(e))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function qr(t){return Se(t)("control",e=>{e?D(t.template.$player,"art-mini-progress-bar"):O(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Ur{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){w(t.art)||!e.miniProgressBar||e.isLive||t.add(qr),!w(t.art)&&e.lock&&u&&t.add(jr),w(t.art)||!e.autoPlayback||e.isLive||t.add(Vr),!w(t.art)&&e.autoOrientation&&u&&t.add(Wr),!w(t.art)&&e.fastForward&&u&&!e.isLive&&t.add(Br)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!w(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(w(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(w(t.art))return t;let o=n;const i=st(t,o);if(w(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return w(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),w(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const Xr=new WeakMap;function Gr(t){return!t.closed&&!Xr.get(t)}function Kr(t){Xr.set(t,(Xr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Xr.get(t)||1)-1;r?Xr.set(t,r):Xr.delete(t)}}const Zr=new WeakMap,Jr=new WeakMap,Qr=["$parent","$parents","$option","$events","$formatted"];function tn(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=Zr.get(r);if(!t||!t.owner.active||t.owner.scope?.closed||!t.option.includes(r))return!1;if(!t.parent)return t.owner.root===t.option;if(Zr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function en(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function rn(t){const e=Zr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function nn(t,e){for(let r=0;r{l&&l!==r&&l.dispose()},()=>un(t,o)])try{e()}catch(d){d instanceof h?c.push(...d.errors):c.push(d)}if(r.closed||w(t)||(o.push(...i.splice(0)),dn.set(r,o),cn.set(e,r),ln.set(e,n)),a(),c.length)throw new h(c)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function gn(t,e,r,n,o,i){const a=i||fn(e);if(!Gr(a)||w(t))return;const s=t.proxy(r,n,e=>{if(Gr(a)&&!w(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Gr(a)||w(t)?t.events.remove(s):(rn(e).events.push(s),i&&i!==cn.get(e)&&i.add(()=>{const r=rn(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function vn(t,e,r,n){const o=fn(e);if(!Gr(o)||w(t))return;const i=(...e)=>{if(Gr(o)&&!w(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function yn(t){const e=t.ownerDocument.defaultView?.getComputedStyle(t).visibility;return t.isConnected&&!t.matches(":disabled")&&!t.closest("[inert]")&&"true"!==t.getAttribute("aria-disabled")&&t.getClientRects().length>0&&"hidden"!==e&&"collapse"!==e}function bn(t){return Array.from(t.querySelectorAll('[tabindex="0"],button,input,select,textarea,a[href],[contenteditable]')).filter(t=>"-1"!==t.getAttribute("tabindex")&&yn(t))}function wn(t,e,r=!1){if(!t.show||w(t.art)||!t.active)return;const n=t.cache.get(t.active);if(!n||!Gr(an(n)))return;const o=bn(n),i=n.querySelector(".art-setting-item.art-current"),a=o.find(t=>e===t||e?.contains(t))||(r?o[o.length-1]:o.find(t=>i?.contains(t))||o.find(t=>!t.classList.contains("art-setting-item-back"))||o[0]);a?.focus({preventScroll:!0}),w(t.art)||a?.scrollIntoView({block:"nearest",inline:"nearest"})}function xn(t){const e=t.$parent.ownerDocument,r=e.activeElement,n=t.$parent.contains(r);return o=>{n&&!w(t.art)&&(e.activeElement===e.body||e.activeElement===r&&!r?.getClientRects().length)&&wn(t,o)}}function kn(t){const{art:e}=t,r=b(e).child();if(r.closed)return;const n=()=>t.$parent.ownerDocument;let o=!1;const i=()=>{t.show=!1,r.closed||w(e)||t.render()},a=i=>{r.closed||w(e)||(i?n().activeElement===e.controls.setting&&e.template.$player.classList.contains("art-keyboard-focus")&&wn(t,void 0,o):t.$parent.contains(n().activeElement)&&function(t){const{art:e,$parent:r}=t,n=e.template.$player,o=r.ownerDocument,i=e.controls.setting;!w(e)&&r.contains(o.activeElement)&&(i&&n.contains(i)&&yn(i)&&i.focus({preventScroll:!0}),(o.activeElement===o.body||r.contains(o.activeElement))&&Et(e))}(t))};e.on("setting",a),r.add(()=>{e.off("setting",a)}),ht(r,e.template.$player,"keydown",r=>{const n=r;if(!bt(n)||n.defaultPrevented||w(e))return;const a=n.target;if(a===e.controls.setting){if("ArrowDown"===n.key||"ArrowUp"===n.key)if(yt(n),t.show)wn(t,void 0,"ArrowUp"===n.key);else{o="ArrowUp"===n.key;try{t.show=!0}finally{o=!1}}else"Escape"===n.key&&t.show&&(yt(n),i());return}if(!t.show||!t.$parent.contains(a))return;if("Escape"===n.key)return yt(n),void i();const s=a.closest(".art-setting-item");if(!s||a!==s&&!a.matches('button,a[href],[role="button"]'))return;const c=t.active&&t.cache.get(t.active);if(!c)return;const l=t.active?.find(t=>t.$item===s);if(!Gr(an(c))||l&&!Gr(fn(l)))return void(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End"].includes(n.key)&&yt(n));const d=bn(c),u=d.indexOf(a);if(u<0)return;let p;switch(n.key){case"ArrowDown":p=Math.min(u+1,d.length-1);break;case"ArrowUp":p=Math.max(u-1,0);break;case"Home":p=0;break;case"End":p=d.length-1;break;case"ArrowLeft":{const t=c.querySelector(".art-setting-item-back");return yt(n),void t?.click()}case"ArrowRight":return yt(n),void(l?.selector?.length&&a.click());default:return}yt(n),void 0!==p&&wn(t,d[p])});let s=!1;ht(r,t.$parent,"focusout",o=>{const a=o.relatedTarget;a&&(t.$parent.contains(a)||a===e.controls.setting)||s||(s=!0,mt(r,()=>{s=!1,r.closed||w(e)||!t.show||t.$parent.contains(n().activeElement)||n().activeElement===e.controls.setting||i()},0))})}function $n(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:i},template:{$player:a,$setting:s,$bottom:c}}=e;if(!n.setting||!t.show||!r)return;const l=a.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),p=l.width/a.offsetWidth||1,f=(d.left-l.left+d.width/2)/p-a.clientLeft,h=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:c}=t,l=Math.min(Math.max(0,c),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*l));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-l)),left:Math.max(l,Math.min(a-d/2,e-l-d))}}({containerWidth:a.clientWidth,containerHeight:a.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:i,controlCenter:f,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(c).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||u||(f+h.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const En=new WeakMap;function An(t){En.delete(t)}const Cn=new WeakMap;function Sn(t,e){e?Cn.set(t,e):Cn.delete(t)}function Tn(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=Cn.get(t),o=n?.();for(const i of["html","icon","tooltip"]){const t=e.get(i)?.value;t instanceof Node&&r.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{for(const r of Reflect.ownKeys(t))!e.has(r)&&Object.getOwnPropertyDescriptor(t,r)?.configurable&&Reflect.deleteProperty(t,r);for(const[r,n]of e)Object.defineProperty(t,r,n);o?.(),Sn(t,n);for(const{node:t,parent:e,next:n}of r)e?e.insertBefore(t,n?.parentNode===e?n:null):t.parentNode?.removeChild(t)}}function Ln(t){const e=t.$item?.querySelector(".art-setting-range");e&&e.setAttribute("aria-label",t.$html?.textContent||"")}const Pn=new WeakMap;async function Mn(t,e,r,n,o,i,a,s){try{const c=fn(e),l=fn(i),d=(Pn.get(i)||0)+1;Pn.set(i,d);const u=()=>Gr(c)&&Gr(l)&&!w(t.art)&&Pn.get(i)===d;if(s?.(),!u())return;const p=await o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(c){console.warn("ArtPlayer setting callback failed:",c)}}function zn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const Rn=new WeakMap;function On(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof h?e.push(...r.errors):e.push(r)}if(e.length)throw new h(e)}function Dn(t){Rn.get(t)?.()}function In(t,e){const r=t.find(e.name);if(w(t.art))return r||e;if(!r)return t.add(e);const n=xn(t);An(r),Dn(r);const o=Tn(r),i=r.$item,a=i?.parentNode,s=i?.nextSibling,c=i?zn(i):void 0,l=t.active,d=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),u=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=mn(t.art,e);r&&i.push(r)}for(const t of n)a.push(Kr(an(t)))}catch(c){try{On([...i.reverse().map(t=>t.resume),...a])}catch(l){console.warn("ArtPlayer setting restore failed:",l)}throw c}let s=!0;return{items:r,resume(){s&&(s=!1,On([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,On([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>sn(t)),...a]))}}}(t,r);let p=!0,f=!1;const h=()=>{if(!p)return;p=!1;for(const t of u.items)Rn.get(t)===h&&Rn.delete(t);if(w(t.art))return void u.dispose();const e=r.$item;try{On([u.resume,()=>{e&&e!==i&&e.remove()},o,()=>c?.(),()=>{a&&i&&a.insertBefore(i,s?.parentNode===a?s:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&W(t.cache.get(l),"art-current");for(const[e,r,n]of d)t.$parent.style.setProperty(e,r,n)}}]),n(i)}catch(m){console.warn("ArtPlayer setting restore failed:",m)}},m=()=>p&&!w(t.art)&&Rn.get(r)===h;for(const y of u.items)Rn.set(y,h);const g=b(t.art).add(()=>{p=!1;for(const t of u.items)Rn.get(t)===h&&Rn.delete(t);u.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!o?.enumerable||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,m),!m())return r;if(t.format(),!m())return r;if(t.createItem(r,!0),!m())return r;if(f=!0,t.render(),!m())return r;p=!1;for(const t of u.items)Rn.get(t)===h&&Rn.delete(t);return u.dispose(),n(r.$item),r}catch(v){throw m()&&h(),v}finally{g()}}const Nn=new WeakMap;function _n(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(n){r.innerHTML="",N(r,n),"html"===e&&Ln(t)}})}function Wn(t,e,r=!1){const n=function(t){const e=Rn.get(t);return()=>!e||Rn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),i=e.$item;let a="selector";st(e,"switch")&&(a="switch"),st(e,"range")&&(a="range"),st(e,"onClick")&&(a="button");const{icons:s,constructor:c}=t.art;if(!n())return;const l=function(t,e,r=b(t)){const n=cn.get(e);(!n||Gr(n)||n.closed)&&hn(t,e);const o=r.child();return cn.set(e,o),ln.set(e,r),dn.set(o,rn(e).events),o.add(()=>{un(t,dn.get(o))}),o}(t.art,e,an(o)),d=()=>Gr(l)&&!w(t.art)&&n();if(!d())return;const u=document.createElement("div");try{if(Sn(e),O(u,"art-setting-item"),H(u,"height",`${c.SETTING_ITEM_HEIGHT}px`),u.dataset.name=e.name||"",u.dataset.value=String(e.value||""),!d())return;const n=xt(u,'
'),p=xt(u,'
'),f=document.createElement("div");switch(O(f,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;N(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;N(f,t)}else N(f,s.check)}if(N(n,f),!d())return;_n(e,"icon",f);const h=document.createElement("div");O(h,"art-setting-item-left-text");const m=e.html||"";if(!d())return;N(h,m),N(n,h),_n(e,"html",h);const g=document.createElement("div");O(g,"art-setting-item-right-tooltip");const v=e.tooltip||"";if(!d())return;switch(N(g,v),N(p,g),_n(e,"tooltip",g),a){case"switch":{const t=document.createElement("div");O(t,"art-setting-item-right-icon");const r=xt(t,s.switchOn),n=xt(t,s.switchOff),o=e.switch;if(!d())return;H(o?n:r,"display","none"),N(p,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;Sn(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,u.setAttribute("aria-checked",String(Boolean(t))),t?(H(n,"display","none"),H(r,"display",null)):(H(n,"display",null),H(r,"display","none"))}});break}case"range":{const t=document.createElement("div");O(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",N(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,i,String(t))}O(r,"art-setting-range"),N(p,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Sn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),it(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(e.selector?.length){const t=document.createElement("div");O(t,"art-setting-item-right-icon"),N(t,s.arrowRight),N(p,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=fn(e),a=(t,r,n)=>gn(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>Mn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>Mn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return Mn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&O(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>Mn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,u,a),!d())return;it(e,"$item",{configurable:!0,get:()=>u}),function(t,e,r,n,o){"range"!==n?r.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")||("switch"===n?(r.setAttribute("role","switch"),r.setAttribute("aria-checked",String(Boolean(e.switch))),r.setAttribute("aria-disabled",String(!e.onSwitch))):"selector"!==n||e.selector?.length||r.setAttribute("aria-current",String(Boolean(e.default))),wt(o,r,()=>r.click(),()=>Gr(o)&&!w(t.art))):Ln(e)}(t,e,u,a,l),r&&i?.parentNode?i.replaceWith(u):N(o,u),e.mounted&&d()&&mt(l,()=>{if(!w(t.art))try{const r=e.mounted?.call(t.art,u,e);Promise.resolve(r).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(r){console.warn("ArtPlayer setting mounted failed:",r)}},0)}catch(p){try{l.dispose()}catch(f){console.warn("ArtPlayer setting cleanup failed:",f)}throw u.remove(),p}}function Fn(t,e=t.option){if(w(t.art))return;const r=xn(t),n=t.cache.get(e);if(n&&!Gr(an(n)))return;const o=(Nn.get(t)||0)+1;Nn.set(t,o);const i=()=>Nn.get(t)===o&&!w(t.art),a=t.active,s=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),c=()=>{t.active=a,a&&t.cache.has(a)&&W(t.cache.get(a),"art-current");for(const[e,r,n]of s)t.$parent.style.setProperty(e,r,n)};if(t.active=e,n)try{W(n,"art-current"),t.resize()}catch(l){throw i()&&t.cache.get(e)===n&&!an(n).closed&&c(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=b(t.art).child();return on.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),o=()=>!n.closed&&!w(t.art)&&t.cache.get(e)===r,a=[];try{if(!o())return;O(r,"art-setting-panel"),r.setAttribute("role","group"),r.setAttribute("aria-label",e[0]?.$parent?.$html?.textContent||t.art.i18n.get("Settings")),N(t.$parent,r),W(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Jr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=b(e).child(),n=(t,n)=>{if(r.closed||w(e))return;const o=(...t)=>{if(!r.closed&&!w(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=L(r,e.controls.setting),o=L(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||w(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this)),kn(this)}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),vn(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),vn(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(Q(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),vn(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{vn(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){nn(e,t)}check(t){!function(t,e){e?.$parent&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.$item&&t.$item.setAttribute("aria-current",String(t.default)),t.default&&t.$item&&W(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Jr.get(t)||{active:!0},a=[],s=new Set,c=new Set(o),l=(t,e,r)=>{for(let n=0;nrn(t).parent},$parents:{get:()=>rn(t).parents},$option:{get:()=>rn(t).option},$events:{get:()=>rn(t).events},$formatted:{get:()=>!0}}),Zr.set(t,{parent:r,parents:n,option:o,events:a?.events||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return nn(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){$n(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&sn(n)}catch(i){r.push(i)}}try{hn(t.art,e)}catch(i){i instanceof h?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new h(r)}(this,t)}remove(t){const e=xn(this),r=this.find(t);X(r,`Can't find [${t}] in the [setting]`),this.traverse(t=>{An(t),Dn(t)},[r]);const n=r.$option.indexOf(r);r.$option.splice(n,1);const o=r.$item,i=[];for(const s of[()=>this.inactivate(r),()=>o?.remove(),()=>this.render()])try{s()}catch(a){a instanceof h?i.push(...a.errors):i.push(a)}if(i.length)throw new h(i);e()}update(t){return In(this,t)}add(t,e=this.option){if(w(this.art))return t;let r=!1;this.traverse(e=>{r||(r=e===t)});const n=e.length,o=r?void 0:function(t){const e={};En.set(t,e);const r=()=>En.get(t)===e;return{current:r,finish(){r()&&En.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(w(this.art)||o&&!o.current())throw a;if(e[n]===t&&e.splice(n,1),!r&&i){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw a}finally{o?.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");H(i,"height",`${o}px`),O(i,"art-setting-item"),O(i,"art-setting-item-back");const a=xt(i,'
'),s=document.createElement("div");O(s,"art-setting-item-left-icon"),N(s,n),N(a,s),N(a,e.$parent.html),gn(t.art,e.$parent,i,"click",()=>t.render(e.$parents),an(r));const c=an(r);i.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")||wt(c,i,()=>i.click(),()=>Gr(c)&&!w(t.art)),i.setAttribute("aria-label",`${t.art.i18n.get("Back")}: ${i.textContent?.trim()||""}`),N(r,i)}(this,t)}createItem(t,e=!1){Wn(this,t,e)}render(t=this.option){Fn(this,t)}}class Bn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch{return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch{this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch{delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch{this.settings={}}}}const Hn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:opacity var(--art-transition-duration) ease,transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel,.art-control-volume:focus-within .art-volume-panel{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:focus-within .art-mini-close,.art-mini-popup:hover .art-mini-state,.art-mini-popup:focus-within .art-mini-state{opacity:1}.art-mini-popup [role=button]:focus-visible{outline:2px solid #fff;outline-offset:-2px}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-layer-lock{display:flex}.art-video-player.art-lock:not(.art-control-show) .art-layer-lock{opacity:0;pointer-events:none}.art-video-player.art-lock:not(.art-control-show) .art-layer-lock:focus-within{opacity:1;pointer-events:auto}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:opacity var(--art-transition-duration) ease,transform var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover:not(.art-selector-dismissed) .art-selector-list,.art-control-selector.art-selector-open .art-selector-list{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}.art-video-player [tabindex]:focus-visible,.art-video-player input:focus-visible,.art-video-player button:focus-visible,.art-video-player a:focus-visible{outline:2px solid currentColor;outline-offset:-2px}.art-video-player.art-keyboard-focus :focus{outline:2px solid currentColor;outline-offset:-2px}.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom{opacity:1}.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-controls,.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-progress{transform:translateY(0)}';class jn{constructor(t){this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope)?.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}async run(t){if(this.active)try{return await Promise.race([t(),this.cancelled])}finally{this.cancel()}}}const qn=new WeakMap;function Un(t){return qn.get(t)}function Xn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const Gn=Wt;class Kn extends Gn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=b(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return qn.set(t,n),r.add(()=>{Xn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){return this.art.template.$video?.textTracks?.[0]}get activeCues(){return Array.from(this.textTrack?.activeCues||[])}get cues(){return Array.from(this.textTrack?.cues||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?j(r,t):H(r,t,e)}update(){!function(t){const e=Un(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?ot(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i={...o.subtitle,...e,url:t},a=Un(this),s=a.revision+1,c=await this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),c}createTrack(t,e){!function(t,e,r){const n=Un(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,c=s.parentNode,l=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const c=t.textTrack,l=c?i.proxy(c,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(l)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const f=n.track;n.track=u,t.destroyEvent=l,s.onload=null,s.onerror=null,p=!0;try{f?.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&Xn(n)}}catch(f){if(p)throw f;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw f;throw a.$track=s,c&&c.insertBefore(s,l?.parentNode===c?l:null),f}}(this,t,e)}async init(t){const e=Un(this),r=function(t){const e=t.request,r=new jn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:i}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Nt.subtitle),!t.url)return;let a;this.option=t,this.style(t.style);try{if(!r.active)return;const n=await fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const o=await n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||K(e.url)){case"srt":return{vtt:e.onVttLoad(dt(r))};case"ass":return{vtt:e.onVttLoad(pt(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const c=void 0===s?t.url:a=ut(s.vtt);if(!r.active)return;i.innerHTML="";const l=e.trackRevision+1;if(this.url!==c&&this.createTrack("metadata",c),!r.active||e.trackRevision>l)return;return a&&(e.ownedURL=a,a=void 0),c}catch(s){if(!r.active)return;throw i.innerHTML="",n.show=s,s}finally{a&&(e.scope.closed||this.url!==a?URL.revokeObjectURL(a):e.ownedURL=a)}})}}const Zn=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${i}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class Jn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=R(e.container),X(this.$container,`No container element found by ${e.container}`)),X(P(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();X("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),X(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=v.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=y(t);o.rollback=r,v.set(e,t),o.releaseContainer=()=>{v.get(e)===t&&v.delete(e)}}(t,this.$container,zn(this.$container)),function(t,e,r){const n=y(t),o=n.mountingTemplate;n.mountingTemplate=e;try{r()}finally{n.mountingTemplate=o}}(t,this,()=>{this.$container.dataset.artId=String(t.id),this.init()})}static get html(){return Zn}query(t){return R(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Jn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);if(w(this.art))return;!function(t){X(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),F(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&O(this.$player,"art-backdrop"),u&&O(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":O(this.$player,"art-destroy")}}const Qn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class to{on(t,e,r){const n=this.e||(this.e={});let o=Qn(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(Qn(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=Qn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new Jn(this),b(this).closed)return;if(this.events=new Le(this),b(this).closed)return;if(this.storage=new Bn,b(this).closed)return;if(this.icons=new _e(this),b(this).closed)return;if(this.i18n=new Ie(this),b(this).closed)return;if(this.notice=new Xe(this),b(this).closed)return;if(this.player=new Rr(this),b(this).closed)return;if(this.layers=new Be(this),b(this).closed)return;if(this.controls=new be(this),b(this).closed)return;if(this.contextmenu=new Ut(this),b(this).closed)return;if(this.subtitle=new Kn(this),b(this).closed)return;if(this.info=new Ye(this),b(this).closed)return;if(this.loading=new He(this),b(this).closed)return;if(this.hotkey=new Oe(this),b(this).closed)return;if(this.mask=new je(this),b(this).closed)return;if(this.setting=new Yn(this),b(this).closed)return;if(this.plugins=new Ur(this),b(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),no.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${no.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=y(t);return e.rollback=void 0,!e.scope.closed})(this)&&ro.push(this)}catch(r){try{x(this,ro,!0,no.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return ro}static get version(){return i}static get config(){return f}static get utils(){return ft}static get scheme(){return Nt}static get Emitter(){return to}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return Jn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:c?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:navigator?.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){x(this,ro,t,no.REMOVE_SRC_WHEN_DESTROY)}}var oo,io;return no.STYLE=Hn,no.DEBUG=!1,no.CONTEXTMENU=!0,no.NOTICE_TIME=2e3,no.SETTING_WIDTH=250,no.SETTING_ITEM_WIDTH=200,no.SETTING_ITEM_HEIGHT=35,no.RESIZE_TIME=200,no.SCROLL_TIME=200,no.SCROLL_GAP=50,no.AUTO_PLAYBACK_MAX=10,no.AUTO_PLAYBACK_MIN=5,no.AUTO_PLAYBACK_TIMEOUT=3e3,no.RECONNECT_TIME_MAX=5,no.RECONNECT_SLEEP_TIME=1e3,no.CONTROL_HIDE_TIME=3e3,no.DBCLICK_TIME=300,no.DBCLICK_FULLSCREEN=!0,no.MOBILE_DBCLICK_PLAY=!0,no.MOBILE_CLICK_PLAY=!1,no.AUTO_ORIENTATION_TIME=200,no.INFO_LOOP_TIME=1e3,no.FAST_FORWARD_VALUE=3,no.FAST_FORWARD_TIME=1e3,no.TOUCH_MOVE_RATIO=.5,no.VOLUME_STEP=.1,no.SEEK_STEP=5,no.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],no.ASPECT_RATIO=["default","4:3","16:9"],no.FLIP=["normal","horizontal","vertical"],no.FULLSCREEN_WEB_IN_BODY=!0,no.LOG_VERSION=!0,no.USE_RAF=!1,no.REMOVE_SRC_WHEN_DESTROY=!0,oo=no,io=Hn,p&&(window.Artplayer=oo,a("artplayer-style",io),setTimeout(()=>{oo.LOG_VERSION&&console.log(`%c ArtPlayer %c ${oo.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),no}); diff --git a/docs/compiled/artplayer.legacy.js b/docs/compiled/artplayer.legacy.js index 6c9ed6e2c..c243fac38 100644 --- a/docs/compiled/artplayer.legacy.js +++ b/docs/compiled/artplayer.legacy.js @@ -67,4 +67,4 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var h=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const v=globalThis.CUSTOM_USER_AGENT,y=null!=v?v:"undefined"===typeof navigator?"":navigator.userAgent,b=/^(?:(?!chrome|android).)*safari/i.test(y),w=/iPad|iPhone|iPod/i.test(y)&&("undefined"===typeof window||!window.MSStream),x=w||y.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,k=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(y)||x,$="undefined"!==typeof window&&"undefined"!==typeof document;const E={properties:["audioTracks","autoplay","buffered","controller","controls","crossOrigin","currentSrc","currentTime","defaultMuted","defaultPlaybackRate","duration","ended","error","loop","mediaGroup","muted","networkState","paused","playbackRate","played","preload","readyState","seekable","seeking","src","startDate","textTracks","videoTracks","volume"],methods:["addTextTrack","canPlayType","load","play","pause"],events:["abort","canplay","canplaythrough","durationchange","emptied","ended","error","loadeddata","loadedmetadata","loadstart","pause","play","playing","progress","ratechange","seeked","seeking","stalled","suspend","timeupdate","volumechange","waiting"],prototypes:["width","height","videoWidth","videoHeight","poster","webkitDecodedFrameCount","webkitDroppedFrameCount","playsInline","webkitSupportsFullscreen","webkitDisplayingFullscreen","onenterpictureinpicture","onleavepictureinpicture","disablePictureInPicture","cancelVideoFrameCallback","requestVideoFrameCallback","getVideoPlaybackQuality","requestPictureInPicture","webkitEnterFullScreen","webkitEnterFullscreen","webkitExitFullScreen","webkitExitFullscreen"]};class T extends Error{constructor(t){super("Failed to release ArtPlayer resources"),this.errors=t,this.name="ResourceCleanupError"}}class C{constructor(){this.cleanups=new Set,this.disposed=!1}get closed(){return this.disposed}add(t){let e=!0;const r=()=>{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new C,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof T?t.push(...e.errors):t.push(e)}if(t.length)throw new T(t)}}const L=new WeakMap,S=new WeakMap;function P(t){const e=L.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function M(t){return P(t).scope}function z(t){const e=P(t);return e.destroying||e.scope.closed}function A(t,e,r,n,o=!1){var i,a,s;const l=P(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof T?e.errors:[e])}};n&&(null==(i=t.template)?void 0:i.$video)&&d(()=>t.reset()),d(()=>l.scope.dispose()),d(()=>{var e;return null==(e=t.template||l.mountingTemplate)?void 0:e.destroy(r)});const u=e.indexOf(t);-1!==u&&e.splice(u,1),t.isDestroy=!0,o||(null==(a=l.releaseContainer)||a.call(l),l.releaseContainer=void 0),d(()=>t.emit("destroy")),d(()=>l.finalizers.dispose()),o&&l.rollback&&d(l.rollback),l.rollback=void 0,null==(s=l.releaseContainer)||s.call(l),l.releaseContainer=void 0;for(const p of c.slice(1))console.warn("Additional ArtPlayer cleanup failure:",p);if(c.length)throw c[0]}const O=new WeakMap;function R(t,e){const r=M(t).child();return O.set(e,r),r}function I(t){const e=O.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function N(t){var e;null==(e=O.get(t))||e.dispose()}function _(t,e,r,n){const o=I(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function W(t,e){return{on:(r,n)=>{_(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=I(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}function D(t){var e;if(t.composedPath)return t.composedPath();const r=[];let n=t.target;for(;n;)r.push(n),n=null!=(e=n.parentNode)?e:null;return"undefined"===typeof window||r.includes(window)||r.push(window),r}function F(t,e){return D(t).includes(e)}function V(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function Y(t){return t.getBoundingClientRect()}function B(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;";try{document.body.appendChild(t);const e=getComputedStyle(t);return{top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0}}finally{t.remove()}}function H(t,e=document){return e.querySelector(t)}function j(t,e){return t.classList.add(e)}function q(t,e){return t.classList.remove(e)}function U(t,e){return t.classList.contains(e)}function X(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function G(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function K(t,e){G(t).forEach(t=>q(t,e)),j(t,e)}function Z(t,e){return e.parentNode.replaceChild(t,e),t}function J(t){return document.createElement(t)}function Q(t,e,r="top"){k||(t.setAttribute("aria-label",e),j(t,"hint--rounded"),j(t,`hint--${r}`))}function tt(t="",e=""){const r=J("i");return j(r,"art-icon"),j(r,`art-icon-${t}`),X(r,e),r}function et(t,e,r){return t.style[e]=r,t}function rt(t,e){for(const r in e)et(t,r,e[r]);return t}function nt(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new C;let a=!1,s=()=>{};function l(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function c(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void c(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;d(l,()=>c(l)),i.closed||(l.src=e)}catch(e){l(e)}}))}),i.closed||(n.src=t)}catch(u){l(u)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){l(u)}},e.onerror=()=>l(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}class ot extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function it(t,e){if(!t)throw new ot(e);return t}function at(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function st(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function lt(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function ct(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const pt={"&":"&","<":"<",">":">","'":"'",'"':"""},ht={"&":"&","<":"<",">":">","'":"'",""":'"'},ft=/(&|<|>|'|")/g;function mt(t){return t.replace(/[&<>'"]/g,t=>pt[t]||t)}const gt=Object.defineProperty,{hasOwnProperty:vt}=Object.prototype;function yt(t,e){return vt.call(t,e)}function bt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function wt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?wt(o,i):i,gt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function xt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function kt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function $t(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const Et=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:ot,addClass:j,append:X,assToVtt:$t,capitalize:dt,clamp:ct,createElement:J,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:gt,download:lt,errorHandle:it,escape:mt,get:bt,getComposedPath:D,getExt:st,getIcon:tt,getRect:Y,getSafeAreaInsets:B,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:U,includeFromEvent:F,inverseClass:K,isBrowser:$,isIOS:w,isIOS13:x,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:k,isSafari:b,loadImg:function(t,e){return nt(t,e,void 0)},mergeDeep:wt,query:H,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:q,replaceElement:Z,secondToTime:ut,setStyle:et,setStyleText:g,setStyles:rt,siblings:G,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:V,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:Q,unescape:function(t){return t.replace(ft,t=>ht[t]||t)},userAgent:y,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function Tt(t,e){return X(t,e)}function Ct(t,e){return e.querySelector(t)}const Lt="array",St="boolean",Pt="string",Mt="number",zt="object",At="function";function Ot(t,e,r){return it(e===Pt||e===Mt||t instanceof Element,`${r.join(".")} require '${Pt}' or 'Element' type`)}const Rt={html:Ot,disable:`?${St}`,name:`?${Pt}`,index:`?${Mt}`,style:`?${zt}`,click:`?${At}`,mounted:`?${At}`,tooltip:`?${Pt}|${Mt}`,width:`?${Mt}`,selector:`?${Lt}`,onSelect:`?${At}`,switch:`?${St}`,onSwitch:`?${At}`,range:`?${Lt}`,onRange:`?${At}`,onChange:`?${At}`},It={id:Pt,container:Ot,url:Pt,poster:Pt,type:Pt,theme:Pt,lang:Pt,volume:Mt,isLive:St,muted:St,autoplay:St,autoSize:St,autoMini:St,loop:St,flip:St,playbackRate:St,aspectRatio:St,screenshot:St,setting:St,hotkey:St,pip:St,mutex:St,backdrop:St,fullscreen:St,fullscreenWeb:St,subtitleOffset:St,miniProgressBar:St,useSSR:St,playsInline:St,lock:St,gesture:St,fastForward:St,autoPlayback:St,autoOrientation:St,airplay:St,proxy:`?${At}`,plugins:[At],layers:[Rt],contextmenu:[Rt],settings:[Rt],controls:[l(s({},Rt),{position:(t,e,r)=>{const n=["top","left","right"];return it("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${St}`,html:Pt,url:Pt}],highlight:[{time:Mt,text:Pt}],thumbnails:{url:Pt,number:Mt,column:Mt,width:Mt,height:Mt,scale:Mt},subtitle:{url:Pt,name:Pt,type:Pt,style:zt,escape:St,encoding:Pt,onVttLoad:At},moreVideoAttr:zt,i18n:zt,icons:zt,cssVar:zt,customType:zt},Nt=new WeakSet;class _t{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return U(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?j(e,r):q(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(z(this.art))return;const r="function"===typeof t?t(this.art):t;if(z(this.art))return;if(r.html=r.html||"",f(r,Rt),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;it(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=R(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,n);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){j(t,`art-${r}`),j(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):X(e,t),i.html&&X(t,i.html),i.style&&rt(t,i.style),i.tooltip&&Q(t,i.tooltip)}(i,this.$parent,this.name,n,this.id,r),a.closed)return;if(r.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),r.click.call(this.art,this,t))});s.push(t)}if(r.selector&&["left","right"].includes(r.position)&&this.selector(r,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,n,i),c=!0,o.set(n,{$ref:i,events:s,option:r}),r.mounted&&r.mounted.call(this.art,i),i}catch(d){try{N(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw(null==(e=o.get(n))?void 0:e.$ref)===i&&o.delete(n),c&&this[n]===i&&(l?Object.defineProperty(this,n,l):delete this[n]),i.remove(),d}}remove(t){it(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Nt.has(e)){Nt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{N(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Nt.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Wt extends _t{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,R(t,this.$parent),k||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=W(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return l(s({},t),{html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=W(e,t),n=H('[data-value="1"]',t);n&&K(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&K(r,"art-current")})}})}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return l(s({},t),{html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=W(e,t),n=H('[data-value="default"]',t);n&&K(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&K(r,"art-current")})}})}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(dt(t))}`).join("");return l(s({},t),{html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=W(e,t),n=H('[data-value="normal"]',t);n&&K(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&K(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>l(s({},t),{html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return l(s({},t),{html:`ArtPlayer ${m}`})}({name:"version",index:50})),this.add(function(t){return e=>l(s({},t),{html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=Y(e),{height:c,width:d}=Y(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),rt(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{F(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Dt(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||(null==s?void 0:s.aborted))return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{null==s||s.removeEventListener("abort",l)}}),null==s||s.addEventListener("abort",l,{once:!0}),l}function Ft(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Vt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const Yt=new WeakMap,Bt=new WeakMap,Ht=new WeakMap;function jt(t){return Ht.get(t)||M(t)}function qt(t){const e=Yt.get(t),r=Ht.get(t);return()=>Yt.get(t)===e&&(!e||e.active())&&Ht.get(t)===r&&(!r||!r.closed)}function Ut(t){const e=Ht.get(t),r=M(t).child(),n=r.child();Ht.set(t,r),r.add(()=>{Ht.get(t)===r&&Ht.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!z(t)&&!n.closed&&Yt.get(t)===o};return Yt.set(t,o),n.add(()=>{Yt.get(t)===o&&Yt.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function Xt(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function Gt(t,e,r){Bt.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Bt.get(t)===e&&(Bt.delete(t),Xt(e))}}function Kt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Zt(t,e){const{$progress:r}=t.template,{left:n}=Y(r),o=ct((k?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:ut(i),width:o,percentage:ct(o/r.clientWidth,0,1)}}function Jt(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Zt(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Qt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=I(e),{on:a}=W(t,e);let s=()=>{};const l=Ct(".art-progress-hover",e),c=Ct(".art-progress-loaded",e),d=Ct(".art-progress-played",e),u=Ct(".art-progress-highlight",e),p=Ct(".art-progress-indicator",e),h=Ct(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Zt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?et(h,"left",0):o>e.clientWidth-a/2?et(h,"left",e.clientWidth-a+"px"):et(h,"left",o-a/2+"px")}r.indicator?X(p,r.indicator):et(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&k;if("loaded"===r&&et(c,"width",100*n+"%"),"hover"===r&&(et(l,"width",100*n+"%"),F(a,u)?function(r){const{width:n}=Zt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=null!=o?o:"";const i=h.clientWidth;n<=i/2?et(h,"left",0):n>e.clientWidth-i/2?et(h,"left",e.clientWidth-i+"px"):et(h,"left",n-i/2+"px")}(a):f(a),0===n?q(o,"art-progress-hover"):j(o,"art-progress-hover")),"played"===r&&(et(d,"width",100*n+"%"),et(p,"left",100*n+"%")),m){j(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Ft(i,()=>{q(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function te(t){return e=>l(s({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Qt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=W(t,e),a=I(e);let s=0;const l=()=>{const e=qt(t);return()=>!a.closed&&!z(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!k){let e;i(r,"click",e=>{e.target!==n&&Jt(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=Zt(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(null==n?void 0:n()){const{second:o,percentage:i}=Zt(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t)}})}function ee(t){const{option:e}=t.art;e.isLive||t.add(te({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>l(s({},t),{mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.play),s=Tt(t,o.pause);function l(){et(a,"display","flex"),et(s,"display","none")}function c(){et(a,"display","none"),et(s,"display","flex")}Q(a,i.get("Play")),Q(s,i.get("Pause")),n(a,"click",()=>{at(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>l(s({},t),{mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o}=e,i=Tt(t,o.volume),a=Tt(t,o.volumeClose),s=Tt(t,'
'),l=Tt(s,'
'),c=Tt(l,'
'),d=Tt(l,'
'),u=Tt(d,'
'),p=Tt(u,'
'),h=Tt(d,'
');function f(t){const{top:e,height:r}=Y(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)et(i,"display","none"),et(a,"display","flex"),et(h,"top","100%"),et(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;et(i,"display","flex"),et(a,"display","none"),et(h,"top",100-t+"%"),et(p,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),k)et(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>l(s({},t),{style:k?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=W(e,t);function n(){const r=`${ut(e.currentTime)} / ${ut(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!M(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!k&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=W(e,t),{icons:n}=e;Tt(t,n.screenshot),r(t,"click",()=>{at(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e;Tt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{Q(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e;Tt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{Q(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=W(e,t),{icons:n}=e;Tt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenWebOn),s=Tt(t,o.fullscreenWebOff);et(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(Q(t,i.get("Exit Web Fullscreen")),et(a,"display","none"),et(s,"display","inline-flex")):(Q(t,i.get("Web Fullscreen")),et(a,"display","inline-flex"),et(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenOn),s=Tt(t,o.fullscreenOff);et(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(Q(t,i.get("Exit Fullscreen")),et(a,"display","none"),et(s,"display","inline-flex")):(Q(t,i.get("Fullscreen")),et(a,"display","inline-flex"),et(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rne.get(t).option.selector}),gt(t,"$control_item",{get:()=>ne.get(t).item}),gt(t,"$control_value",{get:()=>ne.get(t).value})),ne.set(t,e)}function ie(t,e){t.innerHTML=e}function ae(t,e,r,n,o){const{proxy:i}=t.events,a=I(n),s=r.selector;j(n,"art-control-selector");const l=document.createElement("div");j(l,"art-selector-value"),X(l,r.html),n.textContent="",X(n,l);const d=Tt(n,'
');for(let c=0;cc(null,null,function*(){if(a.closed)return;const o=D(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++u,c=()=>!a.closed&&s===u,d=a.add(function(t,e){return re.set(t,e),()=>{re.get(t)===e&&re.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=yield r.onSelect.call(t,i,i.$control_item,n);c()&&ie(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class se extends _t{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;R(t,n);const{on:o}=W(t,n);o("mousemove",()=>{k||(this.show=!0)}),o("click",()=>{k?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=F(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(q(r,"art-hide-cursor"),j(r,"art-hover"),this.timer=Date.now()):(j(r,"art-hide-cursor"),q(r,"art-hover"))}),this.init(),M(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=I(e),{on:i}=W(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){ee(this)}add(t){if(z(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:it(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){ie(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function le(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(z(t))return;const o=F(r,e);t.isInput=o&&"INPUT"===(null==(n=r.target)?void 0:n.tagName),t.isFocus=o,t.emit(o?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),M(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(z(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),z(t))return;(!k||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),z(t))return;k?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function ce(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!z(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),M(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(z(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:qt(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Jt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=ct((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=ct(i.time+t.duration*d*l,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",ct(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${ut(u)} / ${ut(t.duration)}`))},cancel:r}}const de=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],ue=["resize","scroll","orientationchange"];const pe=new WeakMap;function he(t){const e=pe.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function fe(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=fe(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=he(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(null==o?void 0:o.capture),once:Boolean(null==o?void 0:o.once),passive:null==o?void 0:o.passive,signal:null==o?void 0:o.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||(null==c?void 0:c.aborted))return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,l),null==c||c.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):(null==c?void 0:c.aborted)?p():null==c||c.addEventListener("abort",p,{once:!0})}catch(h){try{u(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return p}function me(t){return(e,r)=>{if(z(t))return;const n=(...e)=>{if(!z(t))return r(...e)};t.on(e,n),M(t).add(()=>{t.off(e,n)})}}function ge(t){if(!t.constructor.USE_RAF)return;const e=M(t);let r=()=>{};const n=()=>{z(t)||(t.playing&&t.emit("raf"),z(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),me(t)("destroy",()=>r())}class ve{constructor(t){this.destroyEvents=new Set,function(t,e){pe.set(t,{scope:M(e),cleaning:!1})}(this,t),M(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),le(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{z(t)||(j(r,"art-hover"),t.emit("hover",!0,e))},e=>{z(t)||(q(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{z(t)||t.emit("mousemove",e)})}(t,this),function(t,e){var r,n;const{option:o,constructor:i}=t,a=me(t);a("resize",()=>{const{aspectRatio:e,notice:r}=t;"standard"===t.state&&o.autoSize&&t.autoSize(),z(t)||(t.aspectRatio=e,z(t)||(r.show=""))});const s=M(t);let l=()=>{};const c=()=>{z(t)||(l(),l=Ft(s,()=>t.emit("resize"),i.RESIZE_TIME))};a("window:orientationchange",c),a("window:resize",c);const d=null==(n=null==(r=t.template.$player.ownerDocument.defaultView)?void 0:r.screen)?void 0:n.orientation;"function"===typeof(null==d?void 0:d.addEventListener)&&e.proxy(d,"change",c)}(t,this),function(t,e){if(!k||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=ce(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=M(t),a=me(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=(null==o?void 0:o.innerHeight)||n.documentElement.clientHeight,a=(null==o?void 0:o.innerWidth)||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),z(t)||(s=!0,Ft(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;M(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){var a;if(z(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||z(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,s=i.window||(null==(a=n.ownerDocument)?void 0:a.defaultView)||window,d=(n,o,i)=>{for(const a of o){if(c())return;l.disposers.push(e.proxy(n,a,e=>{r!==l||z(t)||t.emit(`${i}:${a}`,e)}))}};d(o,de,"document"),d(s,ue,"window")}catch(u){throw o(l),u}if(c())return void o(l);const d=r;r=l,o(d)}i(),e.bindGlobalEvents=i}(t,this),ge(t)}proxy(t,e,r,n={}){return Array.isArray(e),fe(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=he(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function ye(t){if(t&&1===t.nodeType)return t}function be(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const we=new WeakMap;class xe{constructor(t){this.art=t,this.keys={},we.set(this,{subscribed:!1}),k||this.init()}init(){const t=this.art;if(z(t))return;const e=we.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{at(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!z(t)){if(t.isFocus&&function(t,e){var r,n;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const o=function(t,e){var r;const n=t.target;return 9===(null==n?void 0:n.nodeType)?n:(null==n?void 0:n.ownerDocument)||(null==(r=t.view)?void 0:r.document)||e}(t,e);let i=ye(o.activeElement);for(;null==(r=null==i?void 0:i.shadowRoot)?void 0:r.activeElement;)i=ye(i.shadowRoot.activeElement);if(i&&be(i))return!1;const a=ye(null==(n=t.composedPath)?void 0:n.call(t)[0])||ye(t.target);return!a||!be(a)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const ke={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",ke);class $e{constructor(t){this.art=t,this.languages={"zh-cn":ke},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=yt(this.languages,t)&&this.languages[t]||{}}get(t){return yt(this.language,t)&&this.language[t]||t}update(t){this.languages=wt(this.languages,t),this.init()}}const Ee={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class Te{constructor(t){const e=s(s({},Ee),t.option.icons);for(const r in e)gt(this,r,{get:()=>tt(r,e[r])})}}const Ce=new WeakMap;class Le extends _t{constructor(t){super(t),this.name="info",Ce.set(this,{revision:0}),k||this.init()}init(){var t;const e=Ce.get(this),r=++e.revision;if(null==(t=e.scope)||t.dispose(),z(this.art)||e.revision!==r)return;const n=M(this.art).child();e.scope=n,n.add(()=>{e.scope===n&&(e.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!z(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)});const h=()=>{var t;try{for(const e of u){if(!n())return;const r=Reflect.get(c,null!=(t=e.dataset.video)?t:"undefined");if(!n())return;const o="number"===typeof r?r.toFixed(2):r;if(!n())return;if(e.textContent!==o){const t=null==o?null:`${o}`;if(!n())return;e.textContent=t}}n()&&Ft(e,h,a.INFO_LOOP_TIME)}catch(r){o(r)}};n()&&h()}catch(i){o(i)}}(this.art,n,()=>{this.show=!1})}}class Se extends _t{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{et(i,"display","none"),et(s,"display",null),z(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,P(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),z(t)||n.proxy(e.$state,"click",()=>{z(t)||at(t.play())})}}const ze=new WeakMap;function Ae(t){const e=ze.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class Oe{constructor(t){this.art=t,this.timer=null,ze.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),M(t).add(()=>{t.off("destroy",e)}),M(t).add(()=>{this.destroy()})}destroy(){Ae(this)}set show(t){if(z(this.art))return;const e=ze.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){Ae(this);const i=e.revision,a=()=>!z(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(j(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(z(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",z(this.art)||e.revision!==t||q(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else q(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function Re(t,e){return function(t,e){const r=wt(e,t);return r.container=t.container,f(r,It)}(t,e)}function Ie({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ne(t,e){if(!Ie(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Ie(r)?r:void 0}const _e=new WeakMap;function We(t){return _e.get(t)||0}function De(t,e,r,n=!1){const o=e=>{z(t)||r(e)};t[n?"once":"on"](e,o),M(t).add(()=>{t.off(e,o)})}function Fe(t,e,r){for(const[n,o]of e){if(z(t)||r&&!r())return;t[n].show=o}}function Ve(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=jt(t),l=0;return{reset(){l=0,null==a||a.dispose(),q(i,"art-error")},loadStart(){q(i,"art-error")},schedule(d){(d=>c(null,null,function*(){if(z(t))return;const c=jt(t);if(c!==s&&(s=c,l=0),a&&!a.closed)return;const u=c.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!z(t)&&!u.closed&&c===jt(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}const Ye=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],Be=(()=>{if("undefined"===typeof document)return!1;const t=Ye[0],e={};for(const r of Ye){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),He={change:Be.fullscreenchange,error:Be.fullscreenerror},je={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{je.off("change",o),r()};je.on("change",o);const i=t[Be.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!je.isFullscreen)return void t();const r=()=>{je.off("change",r),t()};je.on("change",r);const n=document[Be.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>je.isFullscreen?je.exit():je.request(t,e),onchange(t){je.on("change",t)},onerror(t){je.on("error",t)},on(t,e){const r=He[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=He[t];r&&document.removeEventListener(r,e,!1)},raw:Be};function qe(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(je,{isFullscreen:{get:()=>Boolean(document[Be.fullscreenElement])},element:{enumerable:!0,get:()=>document[Be.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Be.fullscreenEnabled])}});const Ue=new WeakMap;function Xe(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function Ge(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ue.get(t);if(!n){n=new WeakMap,Ue.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Xe(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Xe(i))}function Ke(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,u=!1,p=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!u&&r&&Ge(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Dt(i,t.document,t.changeEvent,m),Dt(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){var e;null==(e=Ue.get(t.document))||e.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,c&&!u&&r&&Ge(t),u?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):p?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Ze(t,e){const r=M(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,u=!1,p=!1;function h(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch(t){}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),h()}),Dt(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=Ue.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||z(t))return;s=r;const o=l,a=()=>z(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),Dt(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!z(t)&&t.emit("fullscreenError",r)}),{get:()=>!z(t)&&i(),set(n){if(z(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?u=!1:d&&(u=!0),null==a||a.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();p=!0,d=c;const s=Ke(e,r,c,()=>{!z(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw z(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const Je=new WeakSet;function Qe(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function tr(t){Je.delete(t),t.removeEventListener("webkitbeginfullscreen",er),t.removeEventListener("webkitpresentationmodechanged",er)}function er(t){var e;if(Je.has(this)&&Qe(this,"webkitbeginfullscreen"===t.type)){tr(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function rr(t){Je.add(t),t.addEventListener("webkitbeginfullscreen",er),t.addEventListener("webkitpresentationmodechanged",er)}function nr(t){const{$video:e}=t.template,r=M(t).child();let n=!1,o=Qe(e),i=o,a=!1,s=0;const l=()=>Qe(e,n);function c(r){if(z(t)||(c=e,Je.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>z(t)||l()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{var t;s++,i=!1,a&&rr(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Dt(r,e,"webkitbeginfullscreen",()=>c(!0)),Dt(r,e,"webkitendfullscreen",()=>c(!1)),Dt(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!z(t)&&l(),set(r){if(z(t))return;const n=++s;if(i=Boolean(r),r){if(tr(e),t.state="fullscreen",z(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,rr(e)),l()&&e.webkitExitFullscreen()}}}function or(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function ir({node:t,parent:e,next:r}){var n;if(!e)return void(null==(n=t.parentNode)||n.removeChild(t));const o=(null==r?void 0:r.parentNode)===e?r:null;t.parentNode===e&&t.nextSibling===o||e.insertBefore(t,o)}function ar(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function sr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function lr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),Dt(o,e,"click",n),Dt(o,l,"click",()=>{at(t.play())}),Dt(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const u=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};Dt(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=ar(i.left,i.top,sr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:u,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function cr(t){const{$player:e,$video:r}=t.template,n=M(t).child();let o,i,a=0,c=!1,d=!1;const u=()=>!z(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{ir(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(z(t))return;const r=++a;d=!1,p(),z(t)||r!==a||(null==o||o.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(z(t))return;const m=++a;if(c)d=!0;else if(t.state="mini",!z(t)&&m===a){null!=i||(i=or(r)),e.classList.add("art-mini");try{if(!o){c=!0;try{o=lr(t,n,u,h)}finally{c=!1}}if(d)return d=!1,void f();if(!o||z(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),z(t)||m!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:l(s({},ar(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,sr(o.element));if(z(t)||m!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),z(t)||m!==a)return;t.storage.set("left",i.left)}z(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,z(t)||m!==a&&!r||(p(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),g}}}return n.add(()=>{a++;try{p()}finally{null==o||o.cancelDrag(),e.classList.remove("art-mini")}}),{get:u,set(t){t?f():h()}}}const dr=new WeakSet,ur=t=>"picture-in-picture"===t.webkitPresentationMode;function pr(t){dr.delete(t),t.removeEventListener("webkitpresentationmodechanged",hr),t.removeEventListener("enterpictureinpicture",hr)}function hr(){var t;if(dr.has(this)&&ur(this)){pr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function fr(t){dr.add(t),t.addEventListener("webkitpresentationmodechanged",hr),t.addEventListener("enterpictureinpicture",hr)}function mr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function gr(t,e,r){return new Promise((n,o)=>{if(z(t)||e===t.url)return void n();const i=Ut(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const d=()=>!s&&i.active(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!d())return;const p=a.child();let h=!1,f=!1,m=!1;const g=function(t,e,r){let n,o=!1,i=!1,a=!1,s=We(t);const l=()=>a||We(t)!==s,c=()=>{var e,r;return!!(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)};return{restore(){if(!r()||l())return;const i=We(t);t.currentTime=e,s=We(t),s>i+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}(t,r,d),v=()=>c(null,null,function*(){if(t.aspectRatio=o,d()){if(n)try{yield t.play()}catch(e){}d()&&(t.notice.show="",l())}}),y=()=>{var e,r;if(d()&&!f&&h)try{if(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)return;if(!d())return;if(m||(m=!0,t.playbackRate=s),!g.ready()||!d()||f)return;f=!0,p.dispose(),v().catch(u)}catch(n){u(n)}},b={"video:error":u,"video:loadedmetadata":()=>{if(d())try{g.restore()}catch(t){u(t)}},"video:canplay":()=>{h=!0,y()},"video:seeked":y,seek:g.manual},w=a.child(),x=[],k=Object.keys(b);for(const e of k)mr(w,t,e,t=>{i.acceptingEvents&&x.push([e,t])},!1);if(Gt(t,i,e),!d())return;if(t.notice.show="",!d())return;const $=()=>{if(w.dispose(),!e)return void l();const r={};for(const e of k)r[e]=mr(p,t,e,b[e],"video:seeked"!==e);for(const[t,e]of x){if(!d()||p.closed)break;r[t](e)}x.length=0};i.assigned?$():i.onAssigned=$}catch(p){u(p)}})}function vr(t){const{option:e,template:{$video:r}}=t;gt(t,"url",{get:()=>r.src,set(n){return c(this,null,function*(){if(z(t))return;const o=function(t){const e=Bt.get(t);return Bt.delete(t),e||Ut(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield Vt(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||st(n),s=e.customType[a];if(a&&s){if(!(yield Vt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;mr(l,t,"video:canplay",()=>{c=!d}),mr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Kt(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||mr(o.scope,t,"video:canplay",e)}}catch(i){Kt(o,i)}finally{Xt(o)}})}})}const yr=[function(t){const{template:{$video:e}}=t;gt(t,"attr",{value(t,r){const n=e;if(void 0===r)return n[t];n[t]=r}})},function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;gt(t,"play",{value(){return c(this,null,function*(){const a=qt(t),s=yield i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})},function(t){const{notice:e}=t;gt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${ut(t.currentTime)} / ${ut(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;gt(t,"forward",{set(e){r.seek=t.currentTime+e}}),gt(t,"backward",{set(e){r.seek=t.currentTime-e}})},function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;gt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=ct(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),gt(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})},function(t){const{$video:e}=t.template;gt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){_e.set(t,We(t)+1)}(t),e.currentTime=ct(n,0,t.duration))}})},function(t){gt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})},function(t){const e=e=>gr(t,e,0);gt(t,"switchQuality",{value:e=>gr(t,e,t.currentTime)}),gt(t,"switchUrl",{value:e}),gt(t,"switch",{set:e})},function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;gt(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;gt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!z(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ne({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(z(t))return;"width"===(null==r?void 0:r.axis)?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,z(t)||t.emit("aspectRatio",i)}}})},function(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=qt(t);return new Promise((a,s)=>{const l=r=>{try{!z(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}gt(t,"getDataURL",{value:()=>o(!1)}),gt(t,"getBlobUrl",{value:()=>o(!0)}),gt(t,"screenshot",{value:e=>c(null,null,function*(){const n=qt(t),o=yield t.getDataURL();if(!z(t)&&n()){const i=e||`artplayer_${ut(r.currentTime)}`;!z(t)&&n()&<(o,`${i}.png`),!z(t)&&n()&&t.emit("screenshot",o)}return o})})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(z(t))return;const i=function(t){const e=je.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>qe(t,e.requestFullscreen,void 0),exit:()=>qe(r,e.exitFullscreen)}}(o);i?gt(t,"fullscreen",Ze(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?gt(t,"fullscreen",nr(t)):gt(t,"fullscreen",{get:()=>!1,set(){z(t)||(r.show=e.get("Fullscreen Not Supported"))}}),gt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),M(t).add(()=>{t.off("video:loadedmetadata",i)})},function(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(ir(t.placement),r()))}return M(t).add(()=>{var t;n+=1;const i=r;if(r=void 0,i)try{o(i,()=>!0)}catch(a){try{e.parentNode!==i.placement.parent&&(null==(t=e.parentNode)||t.removeChild(e))}catch(s){throw new T([a,s])}throw a}}),i=>{if(z(t))return;const a=++n,s=()=>a===n&&!z(t);if(i){r||(r={placement:or(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);gt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})},function(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?gt(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=M(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch(t){}}function u(e,r,n){e.then(()=>{!r||!z(t)&&a||d()},e=>{z(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Dt(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!z(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Dt(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!z(t)&&o()?e:null,set(n){if(z(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",z(t)||c!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?gt(t,"pip",function(t){const{$video:e}=t.template,r=M(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(z(t)||dr.has(e))return;const s=ur(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),z(t)||i!==l||ur(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&fr(e),ur(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Dt(r,e,l,()=>s());return{get:()=>!z(t)&&ur(e),set(r){var n;if(z(t))return;const l=++i,c=a;if(r){if(!1===(null==(n=e.webkitSupportsPresentationMode)?void 0:n.call(e,"picture-in-picture")))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(pr(e),t.state="pip",z(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,fr(e)),ur(e)&&e.webkitSetPresentationMode("inline");z(t)||l!==i||c!==a||ur(e)!==Boolean(r)||s(!0)}}}(t)):gt(t,"pip",{get:()=>!1,set(){z(t)||(r.show=e.get("PIP Not Supported"))}})},function(t){const{$video:e}=t.template,r=t;gt(t,"loaded",{get:()=>r.loadedTime/e.duration}),gt(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})},function(t){gt(t,"played",{get:()=>t.currentTime/t.duration})},function(t){const{$video:e}=t.template;gt(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})},function(t){const{$container:e,$player:r,$video:n}=t.template;gt(t,"autoSize",{value(){if(z(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Ie(o))return;const i=Y(e),a=Ne(i,o.width/o.height);a&&!z(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})},function(t){const e=t;gt(t,"rect",{get:()=>Y(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}gt(t,"x",{get:()=>e.left+window.pageXOffset}),gt(t,"y",{get:()=>e.top+window.pageYOffset})},function(t){const{template:{$player:e},i18n:r,notice:n}=t;gt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){z(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,z(t)||t.emit("flip",o))}})},function(t){gt(t,"mini",cr(t))},function(t){const{template:{$poster:e}}=t;gt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){et(e,"backgroundImage",`url(${t})`)}})},function(t){const{$container:e,$video:r}=t.template;gt(t,"autoHeight",{value(){if(z(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Ie(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||z(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})},function(t){const{$player:e}=t.template;gt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})},function(t){gt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})},function(t){gt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})},function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];gt(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;n{if(!z(t))switch(e.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,z(t)||gt(t,"airplay",{value(){if(!z(t))if(i){const e=o.webkitShowPlaybackTargetPicker;if(z(t))return;Reflect.apply(e,o,[]),z(t)||t.emit("airplay")}else{const n=e.get("AirPlay Not Available");z(t)||(r.show=n)}}}))},function(t){gt(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:(null==i?void 0:i.html)||"",selector:e,onSelect(e,r,i){return c(this,null,function*(){const r=function(t){return t&&re.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!z(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!z(t)&&r()&&(n.show=i)}return e.html})}})}})},function(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,l=M(t).child(),c=!1;function d(){const e=l;l=M(t).child(),o=void 0,c=!1,a=void 0,e.dispose()}function u(){const i=a,c=l;if(!i||!o)return;const d=()=>{var e;return!z(t)&&!c.closed&&l===c&&a===i&&i.sourceActive()&&(null==(e=t.controls)?void 0:e.thumbnails)===i.element};if(!d())return;const u=r.clientWidth*i.percentage;if(!(u>0&&ud-h/2?d-h+"px":u-h/2+"px"}}(e.thumbnails,{imageWidth:o.naturalWidth,videoWidth:n.videoWidth,videoHeight:n.videoHeight,progressWidth:r.clientWidth,position:u}));for(const[t,e]of Object.entries(p)){if(!d())return;et(i.element,t,e)}}me(t)("setBar",(r,n,s)=>{var p;const h=null==(p=t.controls)?void 0:p.thumbnails,{url:f,scale:m}=e.thumbnails;if(!z(t)&&h&&f&&("hover"===r||"played"===r&&s&&k)){if(i!==h){const t=I(h);if(t.closed)return;i=h,t.add(()=>{i===h&&(i=void 0,d())})}if(a={percentage:n,element:h,sourceActive:qt(t)},o)u();else if(!c){const t=l;c=!0,function(t,e,r){return nt(t,e,r)}(f,m,t).then(e=>{l!==t||t.closed||(c=!1,o=e,u())}).catch(e=>{l!==t||t.closed||(c=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),gt(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{z(t)||!e.url||t.option.isLive||z(t)||(t.option.thumbnails=e,d())}})},function(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{z(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Ve(t);!function(t,e){De(t,"video:canplay",()=>{e.reset(),Fe(t,[["loading",!1]])}),De(t,"video:canplay",()=>{Fe(t,[["loading",!1],["controls",!0],["mask",!0]]),z(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;De(t,"video:ended",()=>{if(e.loop){const e=qt(t);if(t.seek=0,z(t)||!e())return;at(t.play()),e()&&Fe(t,[["controls",!1],["mask",!1]],e)}else Fe(t,[["controls",!0],["mask",!0]])})}(t),De(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;De(t,"video:loadedmetadata",()=>{t.emit("resize"),k&&Fe(t,[["loading",!1],["controls",!0],["mask",!0]])}),De(t,"video:loadstart",()=>{e.loadStart(),Fe(t,[["loading",!0],["mask",!1],["controls",!0]])}),De(t,"video:pause",()=>{Fe(t,[["controls",!0],["mask",!0]])}),De(t,"video:play",()=>{Fe(t,[["mask",!1]]),z(t)||et(r,"display","none")}),De(t,"video:playing",()=>Fe(t,[["mask",!1]])),De(t,"video:progress",()=>{t.playing&&Fe(t,[["loading",!1]])}),De(t,"video:seeked",()=>Fe(t,[["loading",!1],["mask",!0]])),De(t,"video:seeking",()=>Fe(t,[["loading",!0],["mask",!1]])),De(t,"video:timeupdate",()=>Fe(t,[["mask",!1]])),De(t,"video:waiting",()=>Fe(t,[["loading",!0],["mask",!1]]))}(t,e)},function(t){if(z(t))return;const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const s in e.moreVideoAttr){if(z(t))return;const r=e.moreVideoAttr[s];if(z(t))return;t.attr(s,r)}if(z(t))return;if(e.muted){const r=e.muted;if(z(t))return;t.muted=r}if(z(t))return;if(e.volume){const r=ct(e.volume,0,1);if(z(t))return;n.volume=r}if(z(t))return;const i=r.get("volume");if(z(t))return;if("number"===typeof i&&(n.volume=ct(i,0,1)),z(t))return;if(e.poster){const r=`url(${e.poster})`;if(z(t))return;et(o,"backgroundImage",r)}if(z(t))return;if(e.autoplay){const r=e.autoplay;if(z(t))return;n.autoplay=r}if(z(t))return;if(e.playsInline){if(z(t))return;if(n.playsInline=!0,z(t))return;n["webkit-playsinline"]=!0}if(z(t))return;if(e.theme){const r=e.cssVar,n=e.theme;if(z(t))return;r["--art-theme"]=n}for(const s in e.cssVar){if(z(t))return;const r=e.cssVar[s];if(z(t))return;t.cssVar(s,r)}if(z(t))return;const a=e.url;z(t)||(t.url=a)}];class br{constructor(t){if(!z(t)){vr(t);for(const e of yr){if(z(t))return;e(t)}}}}const wr=new WeakMap,xr="art-auto-orientation-fullscreen";function kr(t){if(wr.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const $r="art-auto-orientation",Er=["width","height","transform-origin","transform"];function Tr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Ie(t)&&Ie(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=M(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains($r);r.classList.remove($r),n&&(t.isRotate=!1,z(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=B();if(z(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=Er.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add($r),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;z(t)||(r?o?s(!1):e()&&(i(),i=Ft(n,()=>{o||s(!0)},Number(null!=(l=t.constructor.AUTO_ORIENTATION_TIME)?l:0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(xr),t&&(t.cancelled=!0,kr(t),t.settled&&wr.get(t.orientation)===t&&wr.delete(t.orientation))}return M(t).add(o),i=>{var a,s;if(z(t))return;if(!i)return void o();if(n&&!n.cancelled&&wr.get(n.orientation)===n)return;const l=null==(s=null==(a=r.ownerDocument.defaultView)?void 0:a.screen)?void 0:s.orientation;if("function"!==typeof(null==l?void 0:l.lock)||"function"!==typeof l.unlock||!e())return;const c={orientation:l,cancelled:!1,settled:!1};n=c,wr.set(l,c);const d=()=>!z(t)&&!c.cancelled&&n===c&&wr.get(l)===c,u=e=>{c.settled=!0;const o=d();wr.get(l)===c&&wr.delete(l),n===c&&(n=void 0),o&&(r.classList.remove(xr),t.notice.show=e)};try{const t=l.lock(l.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{c.settled=!0,d()?r.classList.add(xr):(kr(c),wr.get(l)===c&&wr.delete(l))}).catch(u)}catch(p){u(p)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),M(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Cr(t){return t.get("times")||{}}function Lr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||z(t))return()=>{};const s=Ct(".art-auto-playback-last",a),l=Ct(".art-auto-playback-jump",a),c=Ct(".art-auto-playback-close",a);Tt(c,r.close);const d=I(a);let u,p=0;const h=()=>{const r=++p;if(null==u||u.dispose(),d.closed||z(t)||p!==r)return;const h=d.child();u=h;const f=()=>u===h&&!h.closed&&!z(t);h.add(()=>{u===h&&(u=void 0,et(a,"display","none"))});const m=jt(t).add(()=>{h.dispose()});h.add(()=>{m()});const g=Cr(n)[t.option.id||t.option.url];if(!f())return;if(et(a,"display","none"),!f()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!f())return;if(et(a,"display","flex"),!f())return;const v=`${e.get("Last Seen")} ${ut(g)}`;if(!f())return;if(s.textContent=v,!f())return;const y=e.get("Jump Play");if(!f())return;if(l.textContent=y,!f())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{f()&&r()});h.add(()=>{t.events.remove(n)})};if(b(c,()=>{et(a,"display","none")}),!f())return;if(b(l,()=>{t.seek=g,f()&&(at(t.play()),f()&&(et(i,"display","none"),f()&&et(a,"display","none")))}),!f())return;let w=()=>{},x=!1;const k=()=>{!x&&f()&&(x=!0,w(),Ft(h,()=>{f()&&et(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",k),w=h.add(()=>{t.off("video:timeupdate",k)}),x&&w()};return()=>{_(t,a,"ready",h),_(t,a,"restart",h)}}(t);return function(t){const{storage:e,constructor:r}=t;me(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Cr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;z(t)||(o.length>i&&delete n[o[0]],n[a]=s,z(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Cr(e)},clear:()=>e.del("times"),delete(t){const r=Cr(e);return delete r[t],e.set("times",r),r}}}function Sr(t){let e,r=0;return{start:n=>{const o=++r;if(null==e||e.scope.dispose(),o!==r||z(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:jt(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{(null==e?void 0:e.active)||q(t.template.$player,"art-fast-forward")}}),Ft(i.scope,()=>{if(e!==i||z(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||z(t))return;t.playbackRate=r,e!==i||i.scope.closed||z(t)||j(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,null==e||e.scope.dispose()}}}function Pr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Sr(t),i=me(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return U(r,"art-fast-forward")}}}function Mr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return U(n,"art-lock")}function i(){z(t)||(j(n,"art-lock"),z(t)||(t.isLock=!0,z(t)||t.emit("lock",!0)))}function a(){z(t)||(q(n,"art-lock"),z(t)||(t.isLock=!1,z(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=I(e);if(n.closed||z(t))return;const o=Tt(e,r.lock);if(n.closed||z(t))return;const i=Tt(e,r.unlock);n.closed||z(t)||(et(o,"display","none"),_(t,e,"lock",e=>{z(t)||(et(o,"display",e?"inline-flex":"none"),n.closed||z(t)||et(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function zr(t){return me(t)("control",e=>{e?q(t.template.$player,"art-mini-progress-bar"):j(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Ar{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){z(t.art)||!e.miniProgressBar||e.isLive||t.add(zr),!z(t.art)&&e.lock&&k&&t.add(Mr),z(t.art)||!e.autoPlayback||e.isLive||t.add(Lr),!z(t.art)&&e.autoOrientation&&k&&t.add(Tr),!z(t.art)&&e.fastForward&&k&&!e.isLive&&t.add(Pr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!z(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(z(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(z(t.art))return t;let o=n;const i=yt(t,o);if(z(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return z(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),z(t.art)||gt(t,o,{value:r})),t}(this,t,e)}}const Or=new WeakMap;function Rr(t){return!t.closed&&!Or.get(t)}function Ir(t){Or.set(t,(Or.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Or.get(t)||1)-1;r?Or.set(t,r):Or.delete(t)}}const Nr=new WeakMap,_r=new WeakMap,Wr=["$parent","$parents","$option","$events","$formatted"];function Dr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Nr.get(o);if(!t||!t.owner.active||(null==(e=t.owner.scope)?void 0:e.closed)||!t.option.includes(o))return!1;if(!t.parent)return t.owner.root===t.option;if((null==(r=Nr.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function Fr(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function Vr(t){const e=Nr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Yr(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>Gr(t,o)])try{e()}catch(d){d instanceof T?l.push(...d.errors):l.push(d)}if(r.closed||z(t)||(o.push(...i.splice(0)),Xr.set(r,o),qr.set(e,r),Ur.set(e,n)),a(),l.length)throw new T(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function tn(t,e,r,n,o,i){const a=i||Zr(e);if(!Rr(a)||z(t))return;const s=t.proxy(r,n,e=>{if(Rr(a)&&!z(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Rr(a)||z(t)?t.events.remove(s):(Vr(e).events.push(s),i&&i!==qr.get(e)&&i.add(()=>{const r=Vr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function en(t,e,r,n){const o=Zr(e);if(!Rr(o)||z(t))return;const i=(...e)=>{if(Rr(o)&&!z(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function rn(t){var e,r;const{art:n,active:o}=t,{controls:i,constructor:{SETTING_WIDTH:a,SETTING_ITEM_HEIGHT:s},template:{$player:l,$setting:c,$bottom:d}}=n;if(!i.setting||!t.show||!o)return;const u=l.getBoundingClientRect(),p=i.setting.getBoundingClientRect(),h=u.width/l.offsetWidth||1,f=(p.left-u.left+p.width/2)/h-l.clientLeft,m=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:l.clientWidth,containerHeight:l.clientHeight,requestedWidth:(null==(r=null==(e=o[0])?void 0:e.$parent)?void 0:r.width)||a,rows:o.length+(o===t.option?0:1),rowHeight:s,controlCenter:f,bottom:Number.parseFloat(getComputedStyle(c).bottom)||0,padding:Number.parseFloat(getComputedStyle(d).paddingLeft)||0});c.style.height=`${m.height}px`,c.style.width=`${m.width}px`,n.isRotate||k||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const nn=new WeakMap;function on(t){nn.delete(t)}const an=new WeakMap;function sn(t,e){e?an.set(t,e):an.delete(t)}function ln(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=an.get(t),i=null==o?void 0:o();for(const a of["html","icon","tooltip"]){const t=null==(e=r.get(a))?void 0:e.value;t instanceof Node&&n.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{var e,a;for(const n of Reflect.ownKeys(t))!r.has(n)&&(null==(e=Object.getOwnPropertyDescriptor(t,n))?void 0:e.configurable)&&Reflect.deleteProperty(t,n);for(const[n,o]of r)Object.defineProperty(t,n,o);null==i||i(),sn(t,o);for(const{node:t,parent:r,next:o}of n)r?r.insertBefore(t,(null==o?void 0:o.parentNode)===r?o:null):null==(a=t.parentNode)||a.removeChild(t)}}const cn=new WeakMap;function dn(t,e,r,n,o,i,a,s){return c(this,null,function*(){try{const l=Zr(e),c=Zr(i),d=(cn.get(i)||0)+1;cn.set(i,d);const u=()=>Rr(l)&&Rr(c)&&!z(t.art)&&cn.get(i)===d;if(null==s||s(),!u())return;const p=yield o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}})}function un(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const pn=new WeakMap;function hn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof T?e.push(...r.errors):e.push(r)}if(e.length)throw new T(e)}function fn(t){var e;null==(e=pn.get(t))||e()}function mn(t,e){const r=t.find(e.name);if(z(t.art))return r||e;if(!r)return t.add(e);on(r),fn(r);const n=ln(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?un(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=Qr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Ir(Hr(t)))}catch(l){try{hn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,hn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,hn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>jr(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)pn.get(t)===h&&pn.delete(t);if(z(t.art))return void d.dispose();const e=r.$item;try{hn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>null==s?void 0:s(),()=>{i&&o&&i.insertBefore(o,(null==a?void 0:a.parentNode)===i?a:null)},()=>t.format(),()=>{if(p){t.active=l,l&&t.cache.has(l)&&K(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(f){console.warn("ArtPlayer setting restore failed:",f)}},f=()=>u&&!z(t.art)&&pn.get(r)===h;for(const v of d.items)pn.set(v,h);const m=M(t.art).add(()=>{u=!1;for(const t of d.items)pn.get(t)===h&&pn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!(null==o?void 0:o.enumerable)||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,f),!f())return r;if(t.format(),!f())return r;if(t.createItem(r,!0),!f())return r;if(p=!0,t.render(),!f())return r;u=!1;for(const t of d.items)pn.get(t)===h&&pn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const gn=new WeakMap;function vn(t,e,r){gt(t,`$${e}`,{configurable:!0,get:()=>r}),gt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",X(r,t)}})}function yn(t,e,r=!1){var n,o;const i=function(t){const e=pn.get(t);return()=>!e||pn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";yt(e,"switch")&&(l="switch"),yt(e,"range")&&(l="range"),yt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=M(t)){const n=qr.get(e);(!n||Rr(n)||n.closed)&&Jr(t,e);const o=r.child();return qr.set(e,o),Ur.set(e,r),Xr.set(o,Vr(e).events),o.add(()=>{Gr(t,Xr.get(o))}),o}(t.art,e,Hr(a)),p=()=>Rr(u)&&!z(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(sn(e),j(h,"art-setting-item"),et(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=Tt(h,'
'),f=Tt(h,'
'),m=document.createElement("div");switch(j(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;X(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;X(m,t)}else X(m,c.check)}if(X(i,m),!p())return;vn(e,"icon",m);const g=document.createElement("div");j(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;X(g,v),X(i,g),vn(e,"html",g);const y=document.createElement("div");j(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(X(y,b),X(f,y),vn(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");j(t,"art-setting-item-right-icon");const r=Tt(t,c.switchOn),n=Tt(t,c.switchOff),o=e.switch;if(!p())return;et(o?n:r,"display","none"),X(f,t),gt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;sn(e,()=>{const t=i;return()=>{i=t}}),gt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(et(n,"display","none"),et(r,"display",null)):(et(n,"display",null),et(r,"display","none"))}});break}case"range":{const t=document.createElement("div");j(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",X(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!p())return;Reflect.set(r,i,String(t))}j(r,"art-setting-range"),X(f,t),gt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;sn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),gt(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(null==(o=e.selector)?void 0:o.length){const t=document.createElement("div");j(t,"art-setting-item-right-icon"),X(t,c.arrowRight),X(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=Zr(e),a=(t,r,n)=>tn(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>dn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>dn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{var o,i;if(null==(o=e.selector)?void 0:o.length)t.render(e.selector);else{if(null==(i=e.$parent)?void 0:i.onSelect)return dn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&j(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>dn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,h,l),!p())return;gt(e,"$item",{configurable:!0,get:()=>h}),r&&(null==s?void 0:s.parentNode)?s.replaceWith(h):X(a,h),e.mounted&&p()&&Ft(u,()=>{var r;if(!z(t.art))try{const n=null==(r=e.mounted)?void 0:r.call(t.art,h,e);Promise.resolve(n).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(n){console.warn("ArtPlayer setting mounted failed:",n)}},0)}catch(f){try{u.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw h.remove(),f}}function bn(t,e=t.option){var r;if(z(t.art))return;const n=t.cache.get(e);if(n&&!Rr(Hr(n)))return;const o=(gn.get(t)||0)+1;gn.set(t,o);const i=()=>gn.get(t)===o&&!z(t.art),a=t.active,s=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),l=()=>{t.active=a,a&&t.cache.has(a)&&K(t.cache.get(a),"art-current");for(const[e,r,n]of s)t.$parent.style.setProperty(e,r,n)};if(t.active=e,n)try{K(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Hr(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=M(t.art).child();return Br.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!z(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;j(n,"art-setting-panel"),X(t.$parent,n),K(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=_r.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=M(e).child(),n=(t,n)=>{if(r.closed||z(e))return;const o=(...t)=>{if(!r.closed&&!z(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=F(r,e.controls.setting),o=F(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||z(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),en(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),en(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(dt(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),en(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{en(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Yr(e,t)}check(t){!function(t,e){(null==e?void 0:e.$parent)&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&K(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=_r.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;oVr(t).parent},$parents:{get:()=>Vr(t).parents},$option:{get:()=>Vr(t).option},$events:{get:()=>Vr(t).events},$formatted:{get:()=>!0}}),Nr.set(t,{parent:r,parents:n,option:o,events:(null==a?void 0:a.events)||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Yr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){rn(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&jr(n)}catch(i){r.push(i)}}try{Jr(t.art,e)}catch(i){i instanceof T?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new T(r)}(this,t)}remove(t){const e=this.find(t);it(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{on(t),fn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>null==n?void 0:n.remove(),()=>this.render()])try{a()}catch(i){i instanceof T?o.push(...i.errors):o.push(i)}if(o.length)throw new T(o)}update(t){return mn(this,t)}add(t,e=this.option){var r;if(z(this.art))return t;let n=!1;this.traverse(e=>{n||(n=e===t)});const o=e.length,i=n?void 0:function(t){const e={};nn.set(t,e);const r=()=>nn.get(t)===e;return{current:r,finish(){r()&&nn.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(z(this.art)||i&&!i.current())throw s;if(e[o]===t&&e.splice(o,1),!n&&a){try{this.inactivate(t)}catch(l){console.warn("ArtPlayer setting cleanup failed:",l)}null==(r=t.$item)||r.remove()}throw s}finally{null==i||i.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");et(i,"height",`${o}px`),j(i,"art-setting-item"),j(i,"art-setting-item-back");const a=Tt(i,'
'),s=document.createElement("div");j(s,"art-setting-item-left-icon"),X(s,n),X(a,s),X(a,e.$parent.html),tn(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Hr(r)),X(r,i)}(this,t)}createItem(t,e=!1){yn(this,t,e)}render(t=this.option){bn(this,t)}}class kn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch(e){return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch(r){this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch(e){delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch(t){this.settings={}}}}const $n='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class En{constructor(t){var e;this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=null==(e=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope))?void 0:e.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}run(t){return c(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const Tn=new WeakMap;function Cn(t){return Tn.get(t)}function Ln(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const Sn=_t;class Pn extends Sn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=M(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return Tn.set(t,n),r.add(()=>{Ln(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){var t,e;return null==(e=null==(t=this.art.template.$video)?void 0:t.textTracks)?void 0:e[0]}get activeCues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.activeCues)||[])}get cues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.cues)||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?rt(r,t):et(r,t,e)}update(){!function(t){const e=Cn(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?mt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return c(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=l(s(s({},o.subtitle),e),{url:t}),a=Cn(this),c=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===c&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=Cn(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(c)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const h=n.track;n.track=u,t.destroyEvent=c,s.onload=null,s.onerror=null,p=!0;try{null==h||h.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&Ln(n)}}catch(h){if(p)throw h;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,(null==c?void 0:c.parentNode)===l?c:null),h}}(this,t,e)}init(t){return c(this,null,function*(){const e=Cn(this),r=function(t){const e=t.request,r=new En(t.scope);return t.request=r,t.revision+=1,null==e||e.cancel(),r}(e),{notice:n,template:{$subtitle:o}}=this.art;return r.run(()=>c(this,null,function*(){if(!this.textTrack)return null;if(f(t,It.subtitle),!t.url)return;let i;this.option=t,this.style(t.style);try{if(!r.active)return;const n=yield fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const a=yield n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||st(e.url)){case"srt":return{vtt:e.onVttLoad(xt(r))};case"ass":return{vtt:e.onVttLoad($t(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=kt(s.vtt);if(!r.active)return;o.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return i&&(e.ownedURL=i,i=void 0),l}catch(a){if(!r.active)return;throw o.innerHTML="",n.show=a,a}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}}))})}}const Mn=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${m}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class zn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=H(e.container),it(this.$container,`No container element found by ${e.container}`)),it(V(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();it("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),it(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=S.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=P(t);o.rollback=r,S.set(e,t),o.releaseContainer=()=>{S.get(e)===t&&S.delete(e)}}(t,this.$container,un(this.$container)),function(t,e,r){const n=P(t),o=n.mountingTemplate;n.mountingTemplate=e;try{r()}finally{n.mountingTemplate=o}}(t,this,()=>{this.$container.dataset.artId=String(t.id),this.init()})}static get html(){return Mn}query(t){return H(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=zn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);if(z(this.art))return;!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),Z(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&j(this.$player,"art-backdrop"),k&&j(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":j(this.$player,"art-destroy")}}const An=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class On{on(t,e,r){const n=this.e||(this.e={});let o=An(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(An(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=An(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new zn(this),M(this).closed)return;if(this.events=new ve(this),M(this).closed)return;if(this.storage=new kn,M(this).closed)return;if(this.icons=new Te(this),M(this).closed)return;if(this.i18n=new $e(this),M(this).closed)return;if(this.notice=new Oe(this),M(this).closed)return;if(this.player=new br(this),M(this).closed)return;if(this.layers=new Se(this),M(this).closed)return;if(this.controls=new se(this),M(this).closed)return;if(this.contextmenu=new Wt(this),M(this).closed)return;if(this.subtitle=new Pn(this),M(this).closed)return;if(this.info=new Le(this),M(this).closed)return;if(this.loading=new Pe(this),M(this).closed)return;if(this.hotkey=new xe(this),M(this).closed)return;if(this.mask=new Me(this),M(this).closed)return;if(this.setting=new xn(this),M(this).closed)return;if(this.plugins=new Ar(this),M(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Nn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Nn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=P(t);return e.rollback=void 0,!e.scope.closed})(this)&&In.push(this)}catch(r){try{A(this,In,!0,Nn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return In}static get version(){return m}static get config(){return E}static get utils(){return Et}static get scheme(){return It}static get Emitter(){return On}static get validator(){return f}static get kindOf(){return f.kindOf}static get html(){return zn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:b?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:null==navigator?void 0:navigator.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){A(this,In,t,Nn.REMOVE_SRC_WHEN_DESTROY)}}var _n,Wn;return Nn.STYLE=$n,Nn.DEBUG=!1,Nn.CONTEXTMENU=!0,Nn.NOTICE_TIME=2e3,Nn.SETTING_WIDTH=250,Nn.SETTING_ITEM_WIDTH=200,Nn.SETTING_ITEM_HEIGHT=35,Nn.RESIZE_TIME=200,Nn.SCROLL_TIME=200,Nn.SCROLL_GAP=50,Nn.AUTO_PLAYBACK_MAX=10,Nn.AUTO_PLAYBACK_MIN=5,Nn.AUTO_PLAYBACK_TIMEOUT=3e3,Nn.RECONNECT_TIME_MAX=5,Nn.RECONNECT_SLEEP_TIME=1e3,Nn.CONTROL_HIDE_TIME=3e3,Nn.DBCLICK_TIME=300,Nn.DBCLICK_FULLSCREEN=!0,Nn.MOBILE_DBCLICK_PLAY=!0,Nn.MOBILE_CLICK_PLAY=!1,Nn.AUTO_ORIENTATION_TIME=200,Nn.INFO_LOOP_TIME=1e3,Nn.FAST_FORWARD_VALUE=3,Nn.FAST_FORWARD_TIME=1e3,Nn.TOUCH_MOVE_RATIO=.5,Nn.VOLUME_STEP=.1,Nn.SEEK_STEP=5,Nn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Nn.ASPECT_RATIO=["default","4:3","16:9"],Nn.FLIP=["normal","horizontal","vertical"],Nn.FULLSCREEN_WEB_IN_BODY=!0,Nn.LOG_VERSION=!0,Nn.USE_RAF=!1,Nn.REMOVE_SRC_WHEN_DESTROY=!0,_n=Nn,Wn=$n,$&&(window.Artplayer=_n,g("artplayer-style",Wn),setTimeout(()=>{_n.LOG_VERSION&&console.log(`%c ArtPlayer %c ${_n.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Nn}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var f=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const g=globalThis.CUSTOM_USER_AGENT,y=null!=g?g:"undefined"===typeof navigator?"":navigator.userAgent,b=/^(?:(?!chrome|android).)*safari/i.test(y),w=/iPad|iPhone|iPod/i.test(y)&&("undefined"===typeof window||!window.MSStream),x=w||y.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,k=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(y)||x,$="undefined"!==typeof window&&"undefined"!==typeof document;const E={properties:["audioTracks","autoplay","buffered","controller","controls","crossOrigin","currentSrc","currentTime","defaultMuted","defaultPlaybackRate","duration","ended","error","loop","mediaGroup","muted","networkState","paused","playbackRate","played","preload","readyState","seekable","seeking","src","startDate","textTracks","videoTracks","volume"],methods:["addTextTrack","canPlayType","load","play","pause"],events:["abort","canplay","canplaythrough","durationchange","emptied","ended","error","loadeddata","loadedmetadata","loadstart","pause","play","playing","progress","ratechange","seeked","seeking","stalled","suspend","timeupdate","volumechange","waiting"],prototypes:["width","height","videoWidth","videoHeight","poster","webkitDecodedFrameCount","webkitDroppedFrameCount","playsInline","webkitSupportsFullscreen","webkitDisplayingFullscreen","onenterpictureinpicture","onleavepictureinpicture","disablePictureInPicture","cancelVideoFrameCallback","requestVideoFrameCallback","getVideoPlaybackQuality","requestPictureInPicture","webkitEnterFullScreen","webkitEnterFullscreen","webkitExitFullScreen","webkitExitFullscreen"]};class A extends Error{constructor(t){super("Failed to release ArtPlayer resources"),this.errors=t,this.name="ResourceCleanupError"}}class C{constructor(){this.cleanups=new Set,this.disposed=!1}get closed(){return this.disposed}add(t){let e=!0;const r=()=>{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new C,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof A?t.push(...e.errors):t.push(e)}if(t.length)throw new A(t)}}const S=new WeakMap,T=new WeakMap;function L(t){const e=S.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function P(t){return L(t).scope}function M(t){const e=L(t);return e.destroying||e.scope.closed}function z(t,e,r,n,o=!1){var i,a,s;const l=L(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof A?e.errors:[e])}};n&&(null==(i=t.template)?void 0:i.$video)&&d(()=>t.reset()),d(()=>l.scope.dispose()),d(()=>{var e;return null==(e=t.template||l.mountingTemplate)?void 0:e.destroy(r)});const u=e.indexOf(t);-1!==u&&e.splice(u,1),t.isDestroy=!0,o||(null==(a=l.releaseContainer)||a.call(l),l.releaseContainer=void 0),d(()=>t.emit("destroy")),d(()=>l.finalizers.dispose()),o&&l.rollback&&d(l.rollback),l.rollback=void 0,null==(s=l.releaseContainer)||s.call(l),l.releaseContainer=void 0;for(const p of c.slice(1))console.warn("Additional ArtPlayer cleanup failure:",p);if(c.length)throw c[0]}const O=new WeakMap;function R(t,e){const r=P(t).child();return O.set(e,r),r}function D(t){const e=O.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function I(t){var e;null==(e=O.get(t))||e.dispose()}function N(t,e,r,n){const o=D(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function _(t,e){return{on:(r,n)=>{N(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=D(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}function W(t){var e;if(t.composedPath)return t.composedPath();const r=[];let n=t.target;for(;n;)r.push(n),n=null!=(e=n.parentNode)?e:null;return"undefined"===typeof window||r.includes(window)||r.push(window),r}function F(t,e){return W(t).includes(e)}function V(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function Y(t){return t.getBoundingClientRect()}function B(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;";try{document.body.appendChild(t);const e=getComputedStyle(t);return{top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0}}finally{t.remove()}}function H(t,e=document){return e.querySelector(t)}function j(t,e){return t.classList.add(e)}function q(t,e){return t.classList.remove(e)}function U(t,e){return t.classList.contains(e)}function X(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function G(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function K(t,e){G(t).forEach(t=>q(t,e)),j(t,e)}function Z(t,e){return e.parentNode.replaceChild(t,e),t}function J(t){return document.createElement(t)}function Q(t,e,r="top"){k||(t.setAttribute("aria-label",e),j(t,"hint--rounded"),j(t,`hint--${r}`))}function tt(t="",e=""){const r=J("i");return j(r,"art-icon"),j(r,`art-icon-${t}`),X(r,e),r}function et(t,e,r){return t.style[e]=r,t}function rt(t,e){for(const r in e)et(t,r,e[r]);return t}function nt(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new C;let a=!1,s=()=>{};function l(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function c(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void c(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;d(l,()=>c(l)),i.closed||(l.src=e)}catch(e){l(e)}}))}),i.closed||(n.src=t)}catch(u){l(u)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){l(u)}},e.onerror=()=>l(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}class ot extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function it(t,e){if(!t)throw new ot(e);return t}function at(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function st(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function lt(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function ct(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const pt={"&":"&","<":"<",">":">","'":"'",'"':"""},ft={"&":"&","<":"<",">":">","'":"'",""":'"'},ht=/(&|<|>|'|")/g;function mt(t){return t.replace(/[&<>'"]/g,t=>pt[t]||t)}const vt=Object.defineProperty,{hasOwnProperty:gt}=Object.prototype;function yt(t,e){return gt.call(t,e)}function bt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function wt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?wt(o,i):i,vt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function xt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function kt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function $t(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const Et=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:ot,addClass:j,append:X,assToVtt:$t,capitalize:dt,clamp:ct,createElement:J,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:vt,download:lt,errorHandle:it,escape:mt,get:bt,getComposedPath:W,getExt:st,getIcon:tt,getRect:Y,getSafeAreaInsets:B,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:U,includeFromEvent:F,inverseClass:K,isBrowser:$,isIOS:w,isIOS13:x,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:k,isSafari:b,loadImg:function(t,e){return nt(t,e,void 0)},mergeDeep:wt,query:H,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:q,replaceElement:Z,secondToTime:ut,setStyle:et,setStyleText:v,setStyles:rt,siblings:G,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:V,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:Q,unescape:function(t){return t.replace(ht,t=>ft[t]||t)},userAgent:y,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function At(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||(null==s?void 0:s.aborted))return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{null==s||s.removeEventListener("abort",l)}}),null==s||s.addEventListener("abort",l,{once:!0}),l}function Ct(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function St(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const Tt=new WeakSet;function Lt(t){Tt.add(t),t.preventDefault()}function Pt(t){return!t.altKey&&!t.ctrlKey&&!t.metaKey&&!t.isComposing&&229!==t.keyCode}function Mt(t,e,r=()=>e.click(),n=()=>!0){if(t.closed)return;e.hasAttribute("role")||e.setAttribute("role","button"),e.hasAttribute("tabindex")||(e.tabIndex=0);let o=!1;const i=()=>n()&&"true"!==e.getAttribute("aria-disabled")&&!e.hasAttribute("disabled"),a=t=>(t.composedPath()[0]||t.target)===e;At(t,e,"keydown",t=>{const e=t;a(e)&&Pt(e)&&!e.defaultPrevented&&("Enter"===e.key?(Lt(e),!e.repeat&&i()&&r()):" "===e.key&&(Lt(e),!e.repeat&&i()&&(o=!0)))}),At(t,e,"keyup",t=>{const n=t;if(" "!==n.key)return;const s=o;o=!1,s&&a(n)&&Pt(n)&&!n.defaultPrevented&&i()&&e.ownerDocument.activeElement===e&&(Lt(n),r())}),At(t,e,"blur",()=>{o=!1}),t.add(()=>{o=!1})}function zt(t,e){return X(t,e)}function Ot(t,e){return e.querySelector(t)}const Rt=new WeakSet;function Dt(t){const e=t.template.$player;!M(t)&&e.isConnected&&(e.hasAttribute("tabindex")||(e.setAttribute("tabindex","-1"),Rt.has(e)||(Rt.add(e),P(t).add(()=>{Rt.delete(e),"-1"===e.getAttribute("tabindex")&&e.removeAttribute("tabindex")}))),e.focus({preventScroll:!0}))}const It=new WeakSet,Nt="[tabindex],button,input,select,textarea,a[href],[contenteditable]";function _t(t){return[t,...t.querySelectorAll(Nt)].find(t=>{var e;if(!t.matches(Nt)||t.tabIndex<0||t.matches(":disabled")||t.closest("[inert]")||"true"===t.getAttribute("aria-disabled")||!t.getClientRects().length)return!1;const r=null==(e=t.ownerDocument.defaultView)?void 0:e.getComputedStyle(t);return"hidden"!==(null==r?void 0:r.visibility)&&"collapse"!==(null==r?void 0:r.visibility)})}function Wt(t,e,r){var n;const o=null==e?void 0:e.ownerDocument,i=null==o?void 0:o.activeElement;if(!["control","contextmenu"].includes(null!=(n=t.name)?n:"")||It.has(t)||!e||!o||!i||!e.contains(i))return()=>{};const a=t.art.template.$player,s=Array.from(a.querySelectorAll(`.art-${t.name}`)),l=s.indexOf(e),c=[...s.slice(l+1),...s.slice(0,l).reverse()];return It.add(t),()=>{var e;if(It.delete(t),M(t.art)||!a.isConnected||o.activeElement!==o.body)return;const n=r?null==(e=t.cache.get(r))?void 0:e.$ref:void 0;for(const t of[...n?[n]:[],...c]){if(!a.contains(t))continue;const e=_t(t);if(e)return void e.focus({preventScroll:!0})}Dt(t.art)}}const Ft="array",Vt="boolean",Yt="string",Bt="number",Ht="object",jt="function";function qt(t,e,r){return it(e===Yt||e===Bt||t instanceof Element,`${r.join(".")} require '${Yt}' or 'Element' type`)}const Ut={html:qt,disable:`?${Vt}`,name:`?${Yt}`,index:`?${Bt}`,style:`?${Ht}`,click:`?${jt}`,mounted:`?${jt}`,tooltip:`?${Yt}|${Bt}`,width:`?${Bt}`,selector:`?${Ft}`,onSelect:`?${jt}`,switch:`?${Vt}`,onSwitch:`?${jt}`,range:`?${Ft}`,onRange:`?${jt}`,onChange:`?${jt}`},Xt={id:Yt,container:qt,url:Yt,poster:Yt,type:Yt,theme:Yt,lang:Yt,volume:Bt,isLive:Vt,muted:Vt,autoplay:Vt,autoSize:Vt,autoMini:Vt,loop:Vt,flip:Vt,playbackRate:Vt,aspectRatio:Vt,screenshot:Vt,setting:Vt,hotkey:Vt,pip:Vt,mutex:Vt,backdrop:Vt,fullscreen:Vt,fullscreenWeb:Vt,subtitleOffset:Vt,miniProgressBar:Vt,useSSR:Vt,playsInline:Vt,lock:Vt,gesture:Vt,fastForward:Vt,autoPlayback:Vt,autoOrientation:Vt,airplay:Vt,proxy:`?${jt}`,plugins:[jt],layers:[Ut],contextmenu:[Ut],settings:[Ut],controls:[l(s({},Ut),{position:(t,e,r)=>{const n=["top","left","right"];return it("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${Vt}`,html:Yt,url:Yt}],highlight:[{time:Bt,text:Yt}],thumbnails:{url:Yt,number:Bt,column:Bt,width:Bt,height:Bt,scale:Bt},subtitle:{url:Yt,name:Yt,type:Yt,style:Ht,escape:Vt,encoding:Yt,onVttLoad:jt},moreVideoAttr:Ht,i18n:Ht,icons:Ht,cssVar:Ht,customType:Ht},Gt=new WeakSet;class Kt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return U(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?j(e,r):q(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(M(this.art))return;const r="function"===typeof t?t(this.art):t;if(M(this.art))return;if(r.html=r.html||"",h(r,Ut),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;it(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=R(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,n);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){j(t,`art-${r}`),j(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):X(e,t),i.html&&X(t,i.html),i.style&&rt(t,i.style),i.tooltip&&Q(t,i.tooltip)}(i,this.$parent,this.name,n,this.id,r),a.closed)return;if(r.click){("control"===this.name&&!r.selector||"contextmenu"===this.name&&!i.querySelector("[data-value]"))&&!i.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")&&Mt(a,i);const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),r.click.call(this.art,this,t))});s.push(t)}if(r.selector&&["left","right"].includes(r.position)&&this.selector(r,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,n,i),c=!0,o.set(n,{$ref:i,events:s,option:r}),r.mounted&&r.mounted.call(this.art,i),i}catch(d){try{I(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw(null==(e=o.get(n))?void 0:e.$ref)===i&&o.delete(n),c&&this[n]===i&&(l?Object.defineProperty(this,n,l):delete this[n]),i.remove(),d}}remove(t){it(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(Gt.has(e))return;const r=Wt(this,e.$ref);Gt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{I(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Gt.delete(e),r()}}update(t){var e;const r=Wt(this,null==(e=this.cache.get(t.name))?void 0:e.$ref,t.name);try{if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}finally{r()}}}function Zt(t){for(const e of t.querySelectorAll("[data-value]"))e.setAttribute("aria-pressed",String(e.classList.contains("art-current")))}function Jt(t,e){var r,n;const o=D(t);if(!o.closed){t.setAttribute("role","group"),t.setAttribute("aria-label",e);for(const i of t.querySelectorAll("[data-value]"))Mt(o,i),i.setAttribute("aria-label",`${e}: ${null!=(n=null==(r=i.textContent)?void 0:r.trim())?n:""}`);Zt(t)}}const Qt=new WeakMap;function te(t,e){e?Qt.set(t,e):Qt.delete(t)}function ee(t){const e=new Set;let r=t;for(;!e.has(r);){e.add(r);let t,n=r;for(;n&&!t;)t=Qt.get(n),n=n.parentElement;if(!t)return r;r=t}return t}function re(t){const e=t;return!!e&&(["INPUT","TEXTAREA","SELECT"].includes(e.tagName)||e.isContentEditable)}function ne(t){var e;const r=null==(e=t.ownerDocument.defaultView)?void 0:e.getComputedStyle(t).visibility;return t.isConnected&&!t.matches(":disabled")&&!t.closest("[inert]")&&"true"!==t.getAttribute("aria-disabled")&&t.getClientRects().length>0&&"hidden"!==r&&"collapse"!==r}class oe extends Kt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,R(t,this.$parent),k||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=_(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join(""),i=r.get("Play Speed");return l(s({},t),{html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=_(e,t),n=H('[data-value="1"]',t);n&&K(n,"art-current"),Jt(t,i),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&(K(r,"art-current"),Zt(t))})}})}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join(""),i=r.get("Aspect Ratio");return l(s({},t),{html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=_(e,t),n=H('[data-value="default"]',t);n&&K(n,"art-current"),Jt(t,i),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&(K(r,"art-current"),Zt(t))})}})}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(dt(t))}`).join(""),i=r.get("Video Flip");return l(s({},t),{html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=_(e,t),n=H('[data-value="normal"]',t);n&&K(n,"art-current"),Jt(t,i),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&(K(r,"art-current"),Zt(t))})}})}}({name:"flip",index:30})),this.add(function(t){return e=>l(s({},t),{html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return l(s({},t),{html:`ArtPlayer ${m}`})}({name:"version",index:50})),this.add(function(t){return e=>l(s({},t),{html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let s=0;s{this.show=!0,i.closed||M(this.art)||!this.show||function(t,e,r){const{$player:n,$contextmenu:o}=t.template,{height:i,width:a,left:s,top:l}=Y(n),{height:c,width:d}=Y(o);let u=e-s,p=r-l;e+d>s+a&&(u=a-d),r+c>l+i&&(p=i-c),M(t)||rt(o,{top:`${p}px`,left:`${u}px`})}(this.art,t,e)},c=function(t,e){const{art:r}=t,{$player:n,$contextmenu:o}=r.template,i=D(o),a=()=>!i.closed&&!M(r);let s,l=!1,c="",d=0;const u=()=>{const t=n.ownerDocument.activeElement;s=t&&n.contains(t)?ee(t):n,te(o,s)},p=()=>Array.from(o.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]")).filter(t=>t.tabIndex>=0&&ne(t)),f=r.i18n.get("Context Menu");if(!a())return{pointer:()=>!1};o.setAttribute("role","group"),o.setAttribute("aria-label",f);const h=t=>{if(!a())return;if(t)return void(o.contains(n.ownerDocument.activeElement)||u());const e=n.ownerDocument.activeElement,i=o.contains(e)||l&&e===n.ownerDocument.body,d=s;s=void 0,l=!1,c="",te(o),i&&(d&&n.contains(d)&&ne(d)&&d.focus({preventScroll:!0}),(n.ownerDocument.activeElement===n.ownerDocument.body||o.contains(n.ownerDocument.activeElement))&&Dt(r))};r.on("contextmenu",h),i.add(()=>{r.off("contextmenu",h),te(o)}),At(i,o,"focusin",()=>{l=!0});let m=!1;return At(i,o,"focusout",e=>{o.contains(e.relatedTarget)||m||(m=!0,Ct(i,()=>{m=!1,a()&&t.show&&!o.contains(n.ownerDocument.activeElement)&&(t.show=!1)},0))}),At(i,n,"keydown",n=>{var i;const s=n;if(!a()||!Pt(s)||s.defaultPrevented)return;if(("ContextMenu"===s.key||"F10"===s.key&&s.shiftKey)&&r.constructor.CONTEXTMENU&&!re(s.target)){Lt(s),u();const r=s.target.getBoundingClientRect();return e(r.left,r.bottom),void(a()&&t.show&&(null==(i=p()[0])||i.focus({preventScroll:!0})))}if(!t.show||!o.contains(s.target))return;if("Escape"===s.key)return Lt(s),void(t.show=!1);if("Tab"===s.key)return void(t.show=!1);if(re(s.target))return;const l=p(),f=l.indexOf(s.target);let h;if("ArrowDown"===s.key||"ArrowRight"===s.key)h=l[(f+1)%l.length];else if("ArrowUp"===s.key||"ArrowLeft"===s.key)h=l[(f+l.length-1)%l.length];else if("Home"===s.key)h=l[0];else if("End"===s.key)h=l[l.length-1];else{if(1!==s.key.length||" "===s.key)return;{const t=s.key.toLowerCase();c=Date.now()-d>700?t:c+t,d=Date.now();const e=[...c].every(e=>e===t)?t:c;h=[...l.slice(f+1),...l.slice(0,f+1)].find(t=>(t.getAttribute("aria-label")||t.textContent||"").trim().toLowerCase().startsWith(e))}}Lt(s),null==h||h.focus({preventScroll:!0})}),{pointer:t=>!(!a()||!r.constructor.CONTEXTMENU||re(t.target))&&(u(),!0)}}(this,a);o(e,"contextmenu",t=>{c.pointer(t)&&(t.preventDefault(),a(t.clientX,t.clientY))}),o(e,"click",t=>{F(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}const ie=new WeakMap,ae=new WeakMap,se=new WeakMap;function le(t){return se.get(t)||P(t)}function ce(t){const e=ie.get(t),r=se.get(t);return()=>ie.get(t)===e&&(!e||e.active())&&se.get(t)===r&&(!r||!r.closed)}function de(t){const e=se.get(t),r=P(t).child(),n=r.child();se.set(t,r),r.add(()=>{se.get(t)===r&&se.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!M(t)&&!n.closed&&ie.get(t)===o};return ie.set(t,o),n.add(()=>{ie.get(t)===o&&ie.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function ue(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function pe(t,e,r){ae.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{ae.get(t)===e&&(ae.delete(t),ue(e))}}function fe(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function he(t,e){const{$progress:r}=t.template,{left:n}=Y(r),o=ct((k?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:ut(i),width:o,percentage:ct(o/r.clientWidth,0,1)}}function me(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=he(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}const ve=new Map([["ArrowRight",1],["ArrowUp",1],["ArrowLeft",-1],["ArrowDown",-1],["PageUp",10],["PageDown",-10]]);function ge(t,e,r,n,o,i="horizontal"){const a=t=>[t.min,t.max,t.value,t.step].every(Number.isFinite)&&t.max>t.min&&t.step>0,s=(t,e)=>Math.min(e.max,Math.max(e.min,t)),l=()=>{if(t.closed)return;const r=n(),o=a(r),i=o?s(r.value,r):0;e.setAttribute("aria-disabled",String(!o)),e.setAttribute("aria-valuemin",String(o?r.min:0)),e.setAttribute("aria-valuemax",String(o?r.max:0)),e.setAttribute("aria-valuenow",String(i)),e.setAttribute("aria-valuetext",r.text(i))};return t.closed||(e.setAttribute("role","slider"),e.tabIndex=0,e.setAttribute("aria-label",r),e.setAttribute("aria-orientation",i),At(t,e,"keydown",t=>{const r=t;if((r.composedPath()[0]||r.target)!==e||!Pt(r)||r.defaultPrevented)return;const i=ve.get(r.key);if(void 0===i&&"Home"!==r.key&&"End"!==r.key)return;Lt(r);const c=n();if(!a(c))return void l();const d="Home"===r.key?c.min:"End"===r.key?c.max:s(c.value,c)+i*c.step;o(s(d,c)),l()}),l()),l}const ye=new WeakMap;function be(t){return ye.get(t)||0}function we(t,e,r){let n,o=!1,i=!1,a=!1,s=be(t);const l=()=>a||be(t)!==s,c=()=>{var e,r;return!!(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)};return{restore(i=()=>{t.currentTime=e}){if(!r()||l())return;const d=be(t);i(),s=be(t),s>d+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}function xe(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=D(e),{on:a}=_(t,e);let s=()=>{};const l=Ot(".art-progress-hover",e),c=Ot(".art-progress-loaded",e),d=Ot(".art-progress-played",e),u=Ot(".art-progress-highlight",e),p=Ot(".art-progress-indicator",e),f=Ot(".art-progress-tip",e);function h(r,n){const{width:o,time:i}=n||he(t,r);f.textContent=i||"00:00";const a=f.clientWidth;o<=a/2?et(f,"left",0):o>e.clientWidth-a/2?et(f,"left",e.clientWidth-a+"px"):et(f,"left",o-a/2+"px")}r.indicator?X(p,r.indicator):et(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&k;if("loaded"===r&&et(c,"width",100*n+"%"),"hover"===r&&(et(l,"width",100*n+"%"),F(a,u)?function(r){const{width:n}=he(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;f.textContent=null!=o?o:"";const i=f.clientWidth;n<=i/2?et(f,"left",0):n>e.clientWidth-i/2?et(f,"left",e.clientWidth-i+"px"):et(f,"left",n-i/2+"px")}(a):h(a),0===n?q(o,"art-progress-hover"):j(o,"art-progress-hover")),"played"===r&&(et(d,"width",100*n+"%"),et(p,"left",100*n+"%")),m){j(o,"art-progress-hover");h(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Ct(i,()=>{q(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function ke(t){return e=>l(s({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{xe(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=_(t,e),a=D(e);let s=0;const l=()=>{const e=ce(t);return()=>!a.closed&&!M(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!k){let e;i(r,"click",e=>{e.target!==n&&me(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=he(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(null==n?void 0:n()){const{second:o,percentage:i}=he(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t),function(t,e){const r=D(e),{on:n}=_(t,e);let o,i=0;const a=ge(r,e,t.i18n.get("Progress"),()=>({min:0,max:t.duration,value:t.currentTime,step:t.constructor.SEEK_STEP,text:e=>`${ut(e)} / ${ut(Number.isFinite(t.duration)&&t.duration>0?t.duration:0)}`}),e=>{const n=++i;null==o||o.dispose();const s=r.child();o=s;const l=le(t).add(()=>{s.dispose()});s.add(()=>{l()}),s.add(()=>{o===s&&(o=void 0)});const c=ce(t),d=()=>n===i&&!s.closed&&!M(t)&&c(),u=we(t,e,d),p=()=>{d()?u.ready()&&(s.dispose(),a()):s.dispose()};for(const r of["video:seeked","video:ended"])t.on(r,p),s.add(()=>{t.off(r,p)});try{t.emit("setBar","played",e/t.duration),d()&&u.restore(()=>{t.seek=e}),p()}catch(f){throw s.dispose(),f}});n("video:loadedmetadata",a),n("video:durationchange",a),n("video:emptied",a),n("video:timeupdate",a),n("video:seeking",a),n("video:seeked",a),n("video:ended",a)}(e,t)}})}function $e(t){const{option:e}=t.art;e.isLive||t.add(ke({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>l(s({},t),{mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e,a=zt(t,o.play),s=zt(t,o.pause);function l(){t.setAttribute("aria-label",i.get("Play")),et(a,"display","flex"),et(s,"display","none")}function c(){t.setAttribute("aria-label",i.get("Pause")),et(a,"display","none"),et(s,"display","flex")}Mt(D(t),t,()=>(e.playing?s:a).click()),Q(a,i.get("Play")),Q(s,i.get("Pause")),n(a,"click",()=>{at(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>l(s({},t),{mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e,a=zt(t,o.volume),s=zt(t,o.volumeClose);for(const e of[a,s])Mt(D(t),e),e.setAttribute("aria-label",i.get("Mute"));const l=zt(t,'
'),c=zt(l,'
'),d=zt(c,'
'),u=zt(c,'
'),p=zt(u,'
'),f=zt(p,'
'),h=zt(u,'
'),m=D(t);let v=0;const g=ge(m,u,i.get("Volume"),()=>({min:0,max:100,value:e.muted?0:100*e.volume,step:100*e.constructor.VOLUME_STEP,text:t=>`${Math.round(t)}%`}),t=>{const r=++v;e.muted=!1,r!==v||m.closed||M(e)||(e.volume=t/100)},"vertical");function y(t){const{top:e,height:r}=Y(u);return 1-(t.clientY-e)/r}function b(){g();const r=t.ownerDocument.activeElement,n=e.muted||0===e.volume,o=n?s:a;if(a.setAttribute("aria-pressed",String(e.muted)),s.setAttribute("aria-pressed",String(e.muted)),n)et(a,"display","none"),et(s,"display","flex"),et(h,"top","100%"),et(f,"top","100%"),d.textContent="0";else{const t=100*e.volume;et(a,"display","flex"),et(s,"display","none"),et(h,"top",100-t+"%"),et(f,"top",100-t+"%"),d.textContent=String(Math.floor(t))}r!==a&&r!==s||r===o||o.focus({preventScroll:!0})}if(b(),r("video:volumechange",b),n(a,"click",()=>{e.muted=!0}),n(s,"click",()=>{e.muted=!1}),k)et(l,"display","none");else{let t=!1;n(u,"mousedown",r=>{t=0===r.button,e.volume=y(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=y(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>l(s({},t),{style:k?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=_(e,t);function n(){const r=`${ut(e.currentTime)} / ${ut(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!P(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!k&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=_(e,t),{icons:n}=e;Mt(D(t),t),zt(t,n.screenshot),r(t,"click",()=>{at(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e;zt(t,o.setting),Mt(D(t),t),t.setAttribute("aria-expanded","false"),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{t.setAttribute("aria-expanded",String(e)),Q(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e;Mt(D(t),t),zt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{Q(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=_(e,t),{icons:n}=e;Mt(D(t),t),zt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e;Mt(D(t),t);const a=zt(t,o.fullscreenWebOn),s=zt(t,o.fullscreenWebOff);et(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(Q(t,i.get("Exit Web Fullscreen")),et(a,"display","none"),et(s,"display","inline-flex")):(Q(t,i.get("Web Fullscreen")),et(a,"display","inline-flex"),et(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e;Mt(D(t),t);const a=zt(t,o.fullscreenOn),s=zt(t,o.fullscreenOff);et(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(Q(t,i.get("Exit Fullscreen")),et(a,"display","none"),et(s,"display","inline-flex")):(Q(t,i.get("Fullscreen")),et(a,"display","inline-flex"),et(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rCe.get(t).option.selector}),vt(t,"$control_item",{get:()=>Ce.get(t).item}),vt(t,"$control_value",{get:()=>Ce.get(t).value})),Ce.set(t,e)}function Te(t,e){t.innerHTML=e}function Le(t,e,r,n,o){const{proxy:i}=t.events,a=D(n),s=r.selector;j(n,"art-control-selector");const l=document.createElement("div");j(l,"art-selector-value"),X(l,r.html),n.textContent="",X(n,l);const d=zt(n,'
');for(let c=0;cc(null,null,function*(){var o,i;if(a.closed)return;const s=W(n),c=r.selector.find(t=>s.includes(t.$control_item));if(!c)return;const d=++u,p=()=>!a.closed&&d===u,f=a.add(function(t,e){return Ee.set(t,e),()=>{Ee.get(t)===e&&Ee.delete(t)}}(n,p));try{if(e(c),a.closed)return;if(r.onSelect){const e=yield r.onSelect.call(t,c,c.$control_item,n);if(p()){const t=l.contains(l.ownerDocument.activeElement);Te(l,e),null==(i=null==(o=Ce.get(c))?void 0:o.refresh)||i.call(o,t)}}}catch(h){console.warn("ArtPlayer selector failed:",h)}finally{f()}}));o.push(p);const f=function(t,e,r,n,o){if(t.closed)return()=>{};const i=Array.from(n.children),a=i.some(t=>t.querySelector(Ae));n.setAttribute("role",a?"group":"listbox"),n.setAttribute("aria-label",o);let s=!1,l=!1,c=!1,d="",u=0;const p=()=>i.length>0&&(l||s&&!c),f=()=>r.querySelector('button,a[href],[role="button"]')||r,h=(e=!1)=>{if(t.closed)return;const n=f();r.querySelector(Ae)?(r.removeAttribute("role"),r.removeAttribute("tabindex")):(r.setAttribute("role","button"),r.tabIndex=0),n!==r&&(r.removeAttribute("aria-haspopup"),r.removeAttribute("aria-expanded"),r.removeAttribute("aria-disabled")),a?n.removeAttribute("aria-haspopup"):n.setAttribute("aria-haspopup","listbox"),n.setAttribute("aria-expanded",String(p())),n.setAttribute("aria-disabled",String(0===i.length)),e&&r.isConnected&&r.ownerDocument.activeElement===r.ownerDocument.body&&n.focus({preventScroll:!0})},m=(t,r=!1)=>{l=t,c=r,e.classList.toggle("art-selector-open",t),e.classList.toggle("art-selector-dismissed",r),h()},v=e=>{e&&!t.closed&&((e.querySelector(Ae)||e).focus({preventScroll:!0}),t.closed||e.scrollIntoView({block:"nearest",inline:"nearest"}))},g=(e=!1)=>{!t.closed&&i.length&&(m(!0),d="",v(i.find(t=>t.classList.contains("art-current"))||i[e?i.length-1:0]))},y=()=>{if(t.closed)return;const o=n.contains(e.ownerDocument.activeElement);m(!1,!0),d="",o&&r.isConnected&&f().focus({preventScroll:!0})};Mt(t,r,()=>{r.click(),e.ownerDocument.activeElement===r&&g()}),h();for(const b of i){const e=b.classList.contains("art-current");a?b.setAttribute("aria-current",String(e)):(b.setAttribute("role","option"),b.setAttribute("aria-selected",String(e))),b.querySelector(Ae)||(b.tabIndex=-1,Mt(t,b,()=>{b.click(),y()}))}return At(t,r,"keydown",t=>{const e=t;!Pt(e)||e.defaultPrevented||e.target!==r&&e.target!==f()||("ArrowDown"===e.key||"ArrowUp"===e.key?(Lt(e),g("ArrowUp"===e.key)):"Escape"===e.key&&p()&&(Lt(e),y()))}),At(t,r,"click",t=>{t.isTrusted&&0===t.detail&&f()!==r&&g()}),At(t,n,"keydown",t=>{var e;const r=t;if(!Pt(r)||r.defaultPrevented)return;if("Escape"===r.key)return Lt(r),void y();const n=i.indexOf(r.target);if(n<0)return;let o;switch(1!==r.key.length&&(d=""),r.key){case"ArrowDown":o=Math.min(n+1,i.length-1);break;case"ArrowUp":o=Math.max(n-1,0);break;case"Home":o=0;break;case"End":o=i.length-1;break;case"ArrowLeft":case"ArrowRight":return void Lt(r);default:{if(1!==r.key.length||" "===r.key)return;const t=Date.now();d=t-u<500?d+r.key.toLocaleLowerCase():r.key.toLocaleLowerCase(),u=t;const a=[...d].every(t=>t===d[0])?d[0]:d;for(let r=1;r<=i.length;r++){const t=(n+r)%i.length;if(null==(e=i[t].textContent)?void 0:e.trim().toLocaleLowerCase().startsWith(a)){o=t;break}}}}Lt(r),void 0!==o&&v(i[o])}),At(t,n,"click",t=>{t.isTrusted&&0===t.detail&&y()}),At(t,e,"mouseenter",()=>{s=!0,m(l)}),At(t,e,"mouseleave",()=>{s=!1,m(n.contains(e.ownerDocument.activeElement))}),At(t,e,"focusout",t=>{e.contains(t.relatedTarget)||m(!1,!0)}),t.add(()=>{e.classList.remove("art-selector-open","art-selector-dismissed")}),h}(a,n,l,d,String(r.tooltip||r.name||l.textContent||t.i18n.get("Open")));for(const c of s)Ce.get(c).refresh=f}class Pe extends Kt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template,o=function(t,e,r){let n,o,i=!0;const a=()=>!t.closed&&i&&e.contains(e.ownerDocument.activeElement),s=()=>{const t=a(),n=e.classList.contains("art-keyboard-focus");e.classList.toggle("art-keyboard-focus",t),t&&!n&&r()},l=()=>{i=!0,s()},c=()=>{i=!1,s()},d=()=>{n!==e.ownerDocument&&(null==o||o.dispose(),n=e.ownerDocument,o=t.child(),At(o,n,"keydown",l,{capture:!0}),At(o,n,"mousedown",c,{capture:!0}),At(o,n,"touchstart",c,{capture:!0,passive:!0}))};return d(),At(t,e,"keydown",l,{capture:!0}),At(t,e,"mousedown",c,{capture:!0}),At(t,e,"touchstart",c,{capture:!0,passive:!0}),At(t,e,"focusin",()=>{d(),s()}),At(t,e,"focusout",()=>{e.classList.remove("art-keyboard-focus")}),t.add(()=>{e.classList.remove("art-keyboard-focus")}),a}(R(t,n),r,()=>{this.show=!0}),{on:i,proxy:a}=_(t,n);a(r,"focusin",e=>{var r;t.isFocus=!0,t.isInput="INPUT"===(null==(r=e.target)?void 0:r.tagName)}),a(r,"focusout",e=>{r.contains(e.relatedTarget)||(t.isFocus=!1,t.isInput=!1)}),i("mousemove",()=>{k||(this.show=!0)}),i("click",()=>{k?this.toggle():this.show=!0}),i("document:mousemove",t=>{this.isHover=F(t,n)}),i("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&!o()&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),i("control",t=>{t?(q(r,"art-hide-cursor"),j(r,"art-hover"),this.timer=Date.now()):(j(r,"art-hide-cursor"),q(r,"art-hover"))}),this.init(),P(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=D(e),{on:i}=_(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){$e(this)}add(t){if(M(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:it(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){var e,r;if(!t)return;const n=t.$control_value.contains(t.$control_value.ownerDocument.activeElement);Te(t.$control_value,t.html);for(let o=0;othis.check(t),t,e,r)}}function Me(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(M(t))return;const o=F(r,e);t.isInput=o&&"INPUT"===(null==(n=r.target)?void 0:n.tagName),t.isFocus=o,t.emit(o?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),P(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(M(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),M(t))return;(!k||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),M(t))return;k?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function ze(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!M(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),P(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(M(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:ce(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{me(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=ct((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=ct(i.time+t.duration*d*l,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",ct(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${ut(u)} / ${ut(t.duration)}`))},cancel:r}}const Oe=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],Re=["resize","scroll","orientationchange"];const De=new WeakMap;function Ie(t){const e=De.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function Ne(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=Ne(t,e,r,n,o);return i.push(a),a})}catch(f){for(const t of i.reverse())try{t()}catch(h){console.warn("Failed to roll back event listener:",h)}throw f}}const i=r,a=Ie(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(null==o?void 0:o.capture),once:Boolean(null==o?void 0:o.once),passive:null==o?void 0:o.passive,signal:null==o?void 0:o.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||(null==c?void 0:c.aborted))return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,l),null==c||c.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):(null==c?void 0:c.aborted)?p():null==c||c.addEventListener("abort",p,{once:!0})}catch(f){try{u(!0)}catch(h){console.warn("Failed to roll back event listener:",h)}throw f}return p}function _e(t){return(e,r)=>{if(M(t))return;const n=(...e)=>{if(!M(t))return r(...e)};t.on(e,n),P(t).add(()=>{t.off(e,n)})}}function We(t){if(!t.constructor.USE_RAF)return;const e=P(t);let r=()=>{};const n=()=>{M(t)||(t.playing&&t.emit("raf"),M(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),_e(t)("destroy",()=>r())}class Fe{constructor(t){this.destroyEvents=new Set,function(t,e){De.set(t,{scope:P(e),cleaning:!1})}(this,t),P(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Me(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{M(t)||(j(r,"art-hover"),t.emit("hover",!0,e))},e=>{M(t)||(q(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{M(t)||t.emit("mousemove",e)})}(t,this),function(t,e){var r,n;const{option:o,constructor:i}=t,a=_e(t);a("resize",()=>{const{aspectRatio:e,notice:r}=t;"standard"===t.state&&o.autoSize&&t.autoSize(),M(t)||(t.aspectRatio=e,M(t)||(r.show=""))});const s=P(t);let l=()=>{};const c=()=>{M(t)||(l(),l=Ct(s,()=>t.emit("resize"),i.RESIZE_TIME))};a("window:orientationchange",c),a("window:resize",c);const d=null==(n=null==(r=t.template.$player.ownerDocument.defaultView)?void 0:r.screen)?void 0:n.orientation;"function"===typeof(null==d?void 0:d.addEventListener)&&e.proxy(d,"change",c)}(t,this),function(t,e){if(!k||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=ze(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=P(t),a=_e(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=(null==o?void 0:o.innerHeight)||n.documentElement.clientHeight,a=(null==o?void 0:o.innerWidth)||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),M(t)||(s=!0,Ct(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;P(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){var a;if(M(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||M(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,s=i.window||(null==(a=n.ownerDocument)?void 0:a.defaultView)||window,d=(n,o,i)=>{for(const a of o){if(c())return;l.disposers.push(e.proxy(n,a,e=>{r!==l||M(t)||t.emit(`${i}:${a}`,e)}))}};d(o,Oe,"document"),d(s,Re,"window")}catch(u){throw o(l),u}if(c())return void o(l);const d=r;r=l,o(d)}i(),e.bindGlobalEvents=i}(t,this),We(t)}proxy(t,e,r,n={}){return Array.isArray(e),Ne(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=Ie(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function Ve(t){if(t&&1===t.nodeType)return t}function Ye(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}function Be(t,e){var r,n,o,i;if(function(t){return Tt.has(t)}(t)||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const a=function(t,e){var r;const n=t.target;return 9===(null==n?void 0:n.nodeType)?n:(null==n?void 0:n.ownerDocument)||(null==(r=t.view)?void 0:r.document)||e}(t,e);let s=Ve(a.activeElement);for(;null==(r=null==s?void 0:s.shadowRoot)?void 0:r.activeElement;)s=Ve(s.shadowRoot.activeElement);if(s&&Ye(s))return!1;const l=Ve(null==(n=t.composedPath)?void 0:n.call(t)[0])||Ve(t.target),c="Enter"===t.key||"Enter"===t.code||"NumpadEnter"===t.code;if(c||" "===t.key||"Space"===t.code){const t='button,summary,[role="button"],[role="switch"]'+(c?",a[href]":"");if((null==(o=null==l?void 0:l.closest)?void 0:o.call(l,t))||(null==(i=null==s?void 0:s.closest)?void 0:i.call(s,t)))return!1}return!l||!Ye(l)}const He=new WeakMap;class je{constructor(t){this.art=t,this.keys={},He.set(this,{subscribed:!1}),k||this.init()}init(){const t=this.art;if(M(t))return;const e=He.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{at(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!M(t)){if(t.isFocus&&Be(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const qe={"Context Menu":"\u5feb\u6377\u83dc\u5355",Lock:"\u9501\u5b9a",Back:"\u8fd4\u56de",Settings:"\u8bbe\u7f6e",Progress:"\u64ad\u653e\u8fdb\u5ea6","Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",qe);class Ue{constructor(t){this.art=t,this.languages={"zh-cn":qe},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=yt(this.languages,t)&&this.languages[t]||{}}get(t){return yt(this.language,t)&&this.language[t]||t}update(t){this.languages=wt(this.languages,t),this.init()}}const Xe={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class Ge{constructor(t){const e=s(s({},Xe),t.option.icons);for(const r in e)vt(this,r,{get:()=>tt(r,e[r])})}}const Ke=new WeakMap;function Ze(t,e,r){const n=()=>!e.closed&&!M(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)}),function(t,e,r){const{$player:n,$info:o,$infoClose:i}=t.template;if(!o)return;const a=()=>!e.closed&&!M(t),s=()=>n.classList.contains("art-info-show"),l=t.i18n.get("Close");if(!a())return;const c=t.i18n.get("Video Info");if(!a())return;i.setAttribute("aria-label",l),o.setAttribute("role","group"),o.setAttribute("aria-label",c),Mt(e,i,()=>i.click(),s),At(e,o,"keydown",t=>{const e=t;a()&&s()&&Pt(e)&&!e.defaultPrevented&&"Escape"===e.key&&(Lt(e),r())});const d=e=>{var r;if(!a())return;const s=n.ownerDocument,l=s.activeElement;if(e)o.contains(l)||(Ke.delete(t),l&&n.contains(l)&&(Ke.set(t,ee(l)),n.classList.contains("art-keyboard-focus")&&i.focus({preventScroll:!0})));else{const e=Ke.get(t);if(Ke.delete(t),!o.contains(l))return;const i=e&&(null==(r=s.defaultView)?void 0:r.getComputedStyle(e).visibility);(null==e?void 0:e.isConnected)&&n.contains(e)&&e.getClientRects().length&&"hidden"!==i&&"collapse"!==i&&!e.matches(":disabled")&&!e.closest("[inert]")&&"true"!==e.getAttribute("aria-disabled")?e.focus({preventScroll:!0}):Dt(t)}};t.on("info",d),e.add(()=>{t.off("info",d)})}(t,e,r);const f=()=>{var t;try{for(const e of u){if(!n())return;const r=Reflect.get(c,null!=(t=e.dataset.video)?t:"undefined");if(!n())return;const o="number"===typeof r?r.toFixed(2):r;if(!n())return;if(e.textContent!==o){const t=null==o?null:`${o}`;if(!n())return;e.textContent=t}}n()&&Ct(e,f,a.INFO_LOOP_TIME)}catch(r){o(r)}};n()&&f()}catch(i){o(i)}}const Je=new WeakMap;class Qe extends Kt{constructor(t){super(t),this.name="info",Je.set(this,{revision:0}),k||this.init()}init(){var t;const e=Je.get(this),r=++e.revision;if(null==(t=e.scope)||t.dispose(),M(this.art)||e.revision!==r)return;const n=P(this.art).child();e.scope=n,n.add(()=>{e.scope===n&&(e.scope=void 0)}),Ze(this.art,n,()=>{this.show=!1})}}class tr extends Kt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{et(i,"display","none"),et(s,"display",null),M(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,L(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),M(t)||n.proxy(e.$state,"click",()=>{M(t)||at(t.play())})}}const nr=new WeakMap;function or(t){const e=nr.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class ir{constructor(t){this.art=t,this.timer=null,nr.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),P(t).add(()=>{t.off("destroy",e)}),P(t).add(()=>{this.destroy()})}destroy(){or(this)}set show(t){if(M(this.art))return;const e=nr.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){or(this);const i=e.revision,a=()=>!M(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(j(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(M(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",M(this.art)||e.revision!==t||q(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else q(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function ar(t,e){return function(t,e){const r=wt(e,t);return r.container=t.container,h(r,Xt)}(t,e)}function sr({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function lr(t,e){if(!sr(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return sr(r)?r:void 0}function cr(t,e,r,n=!1){const o=e=>{M(t)||r(e)};t[n?"once":"on"](e,o),P(t).add(()=>{t.off(e,o)})}function dr(t,e,r){for(const[n,o]of e){if(M(t)||r&&!r())return;t[n].show=o}}function ur(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=le(t),l=0;return{reset(){l=0,null==a||a.dispose(),q(i,"art-error")},loadStart(){q(i,"art-error")},schedule(d){(d=>c(null,null,function*(){if(M(t))return;const c=le(t);if(c!==s&&(s=c,l=0),a&&!a.closed)return;const u=c.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!M(t)&&!u.closed&&c===le(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}const pr=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],fr=(()=>{if("undefined"===typeof document)return!1;const t=pr[0],e={};for(const r of pr){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),hr={change:fr.fullscreenchange,error:fr.fullscreenerror},mr={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{mr.off("change",o),r()};mr.on("change",o);const i=t[fr.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!mr.isFullscreen)return void t();const r=()=>{mr.off("change",r),t()};mr.on("change",r);const n=document[fr.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>mr.isFullscreen?mr.exit():mr.request(t,e),onchange(t){mr.on("change",t)},onerror(t){mr.on("error",t)},on(t,e){const r=hr[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=hr[t];r&&document.removeEventListener(r,e,!1)},raw:fr};function vr(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(mr,{isFullscreen:{get:()=>Boolean(document[fr.fullscreenElement])},element:{enumerable:!0,get:()=>document[fr.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[fr.fullscreenEnabled])}});const gr=new WeakMap;function yr(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function br(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=gr.get(t);if(!n){n=new WeakMap,gr.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),yr(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),yr(i))}function wr(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,u=!1,p=!1;const f=new Promise((t,e)=>{a=t,s=e});function h(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!u&&r&&br(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&h()};if(At(i,t.document,t.changeEvent,m),At(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&h(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){var e;null==(e=gr.get(t.document))||e.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,c&&!u&&r&&br(t),u?Promise.resolve(e).then(()=>{c?n():h()},t=>h(!0,t)).catch(()=>{}):p?h(!0,new Error("Fullscreen request failed")):m()}catch(v){h(!0,v)}return{promise:f,cancel:()=>i.dispose()}}function xr(t,e){const r=P(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,u=!1,p=!1;function f(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch(t){}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),f()}),At(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=gr.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void f();if(r===s||M(t))return;s=r;const o=l,a=()=>M(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),At(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!M(t)&&t.emit("fullscreenError",r)}),{get:()=>!M(t)&&i(),set(n){if(M(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?u=!1:d&&(u=!0),null==a||a.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();p=!0,d=c;const s=wr(e,r,c,()=>{!M(t)&&c||f()},()=>!i());p=!1,l===o?a=s:s.cancel();const h=s.promise.catch(e=>{throw M(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return h.catch(()=>{}),h}}}const kr=new WeakSet;function $r(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Er(t){kr.delete(t),t.removeEventListener("webkitbeginfullscreen",Ar),t.removeEventListener("webkitpresentationmodechanged",Ar)}function Ar(t){var e;if(kr.has(this)&&$r(this,"webkitbeginfullscreen"===t.type)){Er(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function Cr(t){kr.add(t),t.addEventListener("webkitbeginfullscreen",Ar),t.addEventListener("webkitpresentationmodechanged",Ar)}function Sr(t){const{$video:e}=t.template,r=P(t).child();let n=!1,o=$r(e),i=o,a=!1,s=0;const l=()=>$r(e,n);function c(r){if(M(t)||(c=e,kr.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>M(t)||l()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{var t;s++,i=!1,a&&Cr(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),At(r,e,"webkitbeginfullscreen",()=>c(!0)),At(r,e,"webkitendfullscreen",()=>c(!1)),At(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!M(t)&&l(),set(r){if(M(t))return;const n=++s;if(i=Boolean(r),r){if(Er(e),t.state="fullscreen",M(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,Cr(e)),l()&&e.webkitExitFullscreen()}}}function Tr(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Lr({node:t,parent:e,next:r}){var n;if(!e)return void(null==(n=t.parentNode)||n.removeChild(t));const o=(null==r?void 0:r.parentNode)===e?r:null;t.parentNode===e&&t.nextSibling===o||e.insertBefore(t,o)}function Pr(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function Mr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function zr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),Mt(o,e,()=>e.click(),r),Mt(o,i,()=>(t.playing?c:l).click(),r);const d=t.i18n.get("Close");if(o.closed||M(t))return;e.setAttribute("aria-label",d);const u=t.i18n.get("Mini Player");if(o.closed||M(t))return;s.setAttribute("role","group"),s.setAttribute("aria-label",u),At(o,s,"keydown",t=>{const e=t;r()&&Pt(e)&&!e.defaultPrevented&&"Escape"===e.key&&(Lt(e),n())}),At(o,e,"click",n),At(o,l,"click",()=>{at(t.play())}),At(o,c,"click",()=>{t.pause()});const p=()=>{if(o.closed)return;const e=t.i18n.get(t.playing?"Pause":"Play");o.closed||M(t)||(i.setAttribute("aria-label",e),l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};p();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,p),o.add(()=>{t.off(r,p)});const f=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};At(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=Pr(i.left,i.top,Mr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:f,fresh:!0,focus:()=>e.focus({preventScroll:!0})}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function Or(t){const{$player:e,$video:r}=t.template,n=P(t).child();let o,i,a=0,c=!1,d=!1;const u=()=>!M(t)&&e.classList.contains("art-mini"),p=function(t){const e=t.template.$player;let r;return{entering(){var n;const o=e.ownerDocument,i=o.activeElement,a=i&&e.contains(i);(null==(n=t.template.$mini)?void 0:n.contains(i))||(r=a?ee(i):void 0);const s=a&&e.classList.contains("art-keyboard-focus");return e=>{!s||M(t)||o.activeElement!==i&&o.activeElement!==o.body||null==e||e()}},leaving(n){const o=e.ownerDocument,i=null==n?void 0:n.contains(o.activeElement);return()=>{var e;if(!i||M(t)||o.activeElement!==o.body&&!(null==n?void 0:n.contains(o.activeElement)))return;const a=r&&(null==(e=o.defaultView)?void 0:e.getComputedStyle(r).visibility);(null==r?void 0:r.isConnected)&&r.getClientRects().length&&"hidden"!==a&&"collapse"!==a&&"true"!==r.getAttribute("aria-disabled")&&!r.matches(":disabled")&&!r.closest("[inert]")?r.focus({preventScroll:!0}):Dt(t)}}}}(t);function f(){if(i){const e=i,r=a;i=void 0;try{Lr(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(M(t))return;const r=++a;d=!1;const n=p.leaving(t.template.$mini);f(),M(t)||r!==a||(null==o||o.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",n(),M(t)||r!==a||t.emit("mini",!1)))}function m(){if(M(t))return;const v=++a;if(c)return void(d=!0);const g=p.entering();if(t.state="mini",!M(t)&&v===a){null!=i||(i=Tr(r)),e.classList.add("art-mini");try{if(!o){c=!0;try{o=zr(t,n,u,h)}finally{c=!1}}if(d)return d=!1,void m();if(!o||M(t))return;if(v!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),M(t)||v!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:l(s({},Pr(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,Mr(o.element));if(M(t)||v!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),M(t)||v!==a)return;t.storage.set("left",i.left)}M(t)||v!==a||g(o.focus),M(t)||v!==a||t.emit("mini",!0)}catch(y){const r=d;throw d=!1,M(t)||v!==a&&!r||(f(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),y}}}return n.add(()=>{a++;try{f()}finally{null==o||o.cancelDrag(),e.classList.remove("art-mini")}}),{get:u,set(t){t?m():h()}}}const Rr=new WeakSet,Dr=t=>"picture-in-picture"===t.webkitPresentationMode;function Ir(t){Rr.delete(t),t.removeEventListener("webkitpresentationmodechanged",Nr),t.removeEventListener("enterpictureinpicture",Nr)}function Nr(){var t;if(Rr.has(this)&&Dr(this)){Ir(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function _r(t){Rr.add(t),t.addEventListener("webkitpresentationmodechanged",Nr),t.addEventListener("enterpictureinpicture",Nr)}function Wr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function Fr(t,e,r){return new Promise((n,o)=>{if(M(t)||e===t.url)return void n();const i=de(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const d=()=>!s&&i.active(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!d())return;const p=a.child();let f=!1,h=!1,m=!1;const v=we(t,r,d),g=()=>c(null,null,function*(){if(t.aspectRatio=o,d()){if(n)try{yield t.play()}catch(e){}d()&&(t.notice.show="",l())}}),y=()=>{var e,r;if(d()&&!h&&f)try{if(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)return;if(!d())return;if(m||(m=!0,t.playbackRate=s),!v.ready()||!d()||h)return;h=!0,p.dispose(),g().catch(u)}catch(n){u(n)}},b={"video:error":u,"video:loadedmetadata":()=>{if(d())try{v.restore()}catch(t){u(t)}},"video:canplay":()=>{f=!0,y()},"video:seeked":y,seek:v.manual},w=a.child(),x=[],k=Object.keys(b);for(const e of k)Wr(w,t,e,t=>{i.acceptingEvents&&x.push([e,t])},!1);if(pe(t,i,e),!d())return;if(t.notice.show="",!d())return;const $=()=>{if(w.dispose(),!e)return void l();const r={};for(const e of k)r[e]=Wr(p,t,e,b[e],"video:seeked"!==e);for(const[t,e]of x){if(!d()||p.closed)break;r[t](e)}x.length=0};i.assigned?$():i.onAssigned=$}catch(p){u(p)}})}function Vr(t){const{option:e,template:{$video:r}}=t;vt(t,"url",{get:()=>r.src,set(n){return c(this,null,function*(){if(M(t))return;const o=function(t){const e=ae.get(t);return ae.delete(t),e||de(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield St(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||st(n),s=e.customType[a];if(a&&s){if(!(yield St(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;Wr(l,t,"video:canplay",()=>{c=!d}),Wr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>fe(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||Wr(o.scope,t,"video:canplay",e)}}catch(i){fe(o,i)}finally{ue(o)}})}})}const Yr=[function(t){const{template:{$video:e}}=t;vt(t,"attr",{value(t,r){const n=e;if(void 0===r)return n[t];n[t]=r}})},function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;vt(t,"play",{value(){return c(this,null,function*(){const a=ce(t),s=yield i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})},function(t){const{notice:e}=t;vt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${ut(t.currentTime)} / ${ut(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;vt(t,"forward",{set(e){r.seek=t.currentTime+e}}),vt(t,"backward",{set(e){r.seek=t.currentTime-e}})},function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;vt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=ct(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),vt(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})},function(t){const{$video:e}=t.template;vt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){ye.set(t,be(t)+1)}(t),e.currentTime=ct(n,0,t.duration))}})},function(t){vt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})},function(t){const e=e=>Fr(t,e,0);vt(t,"switchQuality",{value:e=>Fr(t,e,t.currentTime)}),vt(t,"switchUrl",{value:e}),vt(t,"switch",{set:e})},function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;vt(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;vt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!M(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=lr({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(M(t))return;"width"===(null==r?void 0:r.axis)?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,M(t)||t.emit("aspectRatio",i)}}})},function(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=ce(t);return new Promise((a,s)=>{const l=r=>{try{!M(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}vt(t,"getDataURL",{value:()=>o(!1)}),vt(t,"getBlobUrl",{value:()=>o(!0)}),vt(t,"screenshot",{value:e=>c(null,null,function*(){const n=ce(t),o=yield t.getDataURL();if(!M(t)&&n()){const i=e||`artplayer_${ut(r.currentTime)}`;!M(t)&&n()&<(o,`${i}.png`),!M(t)&&n()&&t.emit("screenshot",o)}return o})})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(M(t))return;const i=function(t){const e=mr.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>vr(t,e.requestFullscreen,void 0),exit:()=>vr(r,e.exitFullscreen)}}(o);i?vt(t,"fullscreen",xr(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?vt(t,"fullscreen",Sr(t)):vt(t,"fullscreen",{get:()=>!1,set(){M(t)||(r.show=e.get("Fullscreen Not Supported"))}}),vt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),P(t).add(()=>{t.off("video:loadedmetadata",i)})},function(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(Lr(t.placement),r()))}return P(t).add(()=>{var t;n+=1;const i=r;if(r=void 0,i)try{o(i,()=>!0)}catch(a){try{e.parentNode!==i.placement.parent&&(null==(t=e.parentNode)||t.removeChild(e))}catch(s){throw new A([a,s])}throw a}}),i=>{if(M(t))return;const a=++n,s=()=>a===n&&!M(t),l=function(t){var e;const r=null==(e=t.ownerDocument)?void 0:e.activeElement,n=r&&t.contains(r);return()=>{n&&r.isConnected&&t.contains(r)&&r.ownerDocument.activeElement===r.ownerDocument.body&&r.focus({preventScroll:!0})}}(e);if(i){r||(r={placement:Tr(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(c){throw s()&&o(n,s)&&(r=void 0,l()),c}if(!s())return;if(l(),!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;if(l(),!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);vt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})},function(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?vt(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=P(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch(t){}}function u(e,r,n){e.then(()=>{!r||!M(t)&&a||d()},e=>{M(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),At(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!M(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),At(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!M(t)&&o()?e:null,set(n){if(M(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",M(t)||c!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?vt(t,"pip",function(t){const{$video:e}=t.template,r=P(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(M(t)||Rr.has(e))return;const s=Dr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),M(t)||i!==l||Dr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&_r(e),Dr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])At(r,e,l,()=>s());return{get:()=>!M(t)&&Dr(e),set(r){var n;if(M(t))return;const l=++i,c=a;if(r){if(!1===(null==(n=e.webkitSupportsPresentationMode)?void 0:n.call(e,"picture-in-picture")))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(Ir(e),t.state="pip",M(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,_r(e)),Dr(e)&&e.webkitSetPresentationMode("inline");M(t)||l!==i||c!==a||Dr(e)!==Boolean(r)||s(!0)}}}(t)):vt(t,"pip",{get:()=>!1,set(){M(t)||(r.show=e.get("PIP Not Supported"))}})},function(t){const{$video:e}=t.template,r=t;vt(t,"loaded",{get:()=>r.loadedTime/e.duration}),vt(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})},function(t){vt(t,"played",{get:()=>t.currentTime/t.duration})},function(t){const{$video:e}=t.template;vt(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})},function(t){const{$container:e,$player:r,$video:n}=t.template;vt(t,"autoSize",{value(){if(M(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!sr(o))return;const i=Y(e),a=lr(i,o.width/o.height);a&&!M(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})},function(t){const e=t;vt(t,"rect",{get:()=>Y(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}vt(t,"x",{get:()=>e.left+window.pageXOffset}),vt(t,"y",{get:()=>e.top+window.pageYOffset})},function(t){const{template:{$player:e},i18n:r,notice:n}=t;vt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){M(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,M(t)||t.emit("flip",o))}})},function(t){vt(t,"mini",Or(t))},function(t){const{template:{$poster:e}}=t;vt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){et(e,"backgroundImage",`url(${t})`)}})},function(t){const{$container:e,$video:r}=t.template;vt(t,"autoHeight",{value(){if(M(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!sr(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||M(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})},function(t){const{$player:e}=t.template;vt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})},function(t){vt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})},function(t){vt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})},function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];vt(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;n{if(!M(t))switch(e.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,M(t)||vt(t,"airplay",{value(){if(!M(t))if(i){const e=o.webkitShowPlaybackTargetPicker;if(M(t))return;Reflect.apply(e,o,[]),M(t)||t.emit("airplay")}else{const n=e.get("AirPlay Not Available");M(t)||(r.show=n)}}}))},function(t){vt(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:(null==i?void 0:i.html)||"",selector:e,onSelect(e,r,i){return c(this,null,function*(){const r=function(t){return t&&Ee.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!M(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!M(t)&&r()&&(n.show=i)}return e.html})}})}})},function(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,l=P(t).child(),c=!1;function d(){const e=l;l=P(t).child(),o=void 0,c=!1,a=void 0,e.dispose()}function u(){const i=a,c=l;if(!i||!o)return;const d=()=>{var e;return!M(t)&&!c.closed&&l===c&&a===i&&i.sourceActive()&&(null==(e=t.controls)?void 0:e.thumbnails)===i.element};if(!d())return;const u=r.clientWidth*i.percentage;if(!(u>0&&ud-f/2?d-f+"px":u-f/2+"px"}}(e.thumbnails,{imageWidth:o.naturalWidth,videoWidth:n.videoWidth,videoHeight:n.videoHeight,progressWidth:r.clientWidth,position:u}));for(const[t,e]of Object.entries(p)){if(!d())return;et(i.element,t,e)}}_e(t)("setBar",(r,n,s)=>{var p;const f=null==(p=t.controls)?void 0:p.thumbnails,{url:h,scale:m}=e.thumbnails;if(!M(t)&&f&&h&&("hover"===r||"played"===r&&s&&k)){if(i!==f){const t=D(f);if(t.closed)return;i=f,t.add(()=>{i===f&&(i=void 0,d())})}if(a={percentage:n,element:f,sourceActive:ce(t)},o)u();else if(!c){const t=l;c=!0,function(t,e,r){return nt(t,e,r)}(h,m,t).then(e=>{l!==t||t.closed||(c=!1,o=e,u())}).catch(e=>{l!==t||t.closed||(c=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),vt(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{M(t)||!e.url||t.option.isLive||M(t)||(t.option.thumbnails=e,d())}})},function(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{M(t)||t.emit(`video:${e.type}`,e)})}(t);const e=ur(t);!function(t,e){cr(t,"video:canplay",()=>{e.reset(),dr(t,[["loading",!1]])}),cr(t,"video:canplay",()=>{dr(t,[["loading",!1],["controls",!0],["mask",!0]]),M(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;cr(t,"video:ended",()=>{if(e.loop){const e=ce(t);if(t.seek=0,M(t)||!e())return;at(t.play()),e()&&dr(t,[["controls",!1],["mask",!1]],e)}else dr(t,[["controls",!0],["mask",!0]])})}(t),cr(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;cr(t,"video:loadedmetadata",()=>{t.emit("resize"),k&&dr(t,[["loading",!1],["controls",!0],["mask",!0]])}),cr(t,"video:loadstart",()=>{e.loadStart(),dr(t,[["loading",!0],["mask",!1],["controls",!0]])}),cr(t,"video:pause",()=>{dr(t,[["controls",!0],["mask",!0]])}),cr(t,"video:play",()=>{dr(t,[["mask",!1]]),M(t)||et(r,"display","none")}),cr(t,"video:playing",()=>dr(t,[["mask",!1]])),cr(t,"video:progress",()=>{t.playing&&dr(t,[["loading",!1]])}),cr(t,"video:seeked",()=>dr(t,[["loading",!1],["mask",!0]])),cr(t,"video:seeking",()=>dr(t,[["loading",!0],["mask",!1]])),cr(t,"video:timeupdate",()=>dr(t,[["mask",!1]])),cr(t,"video:waiting",()=>dr(t,[["loading",!0],["mask",!1]]))}(t,e)},function(t){if(M(t))return;const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const s in e.moreVideoAttr){if(M(t))return;const r=e.moreVideoAttr[s];if(M(t))return;t.attr(s,r)}if(M(t))return;if(e.muted){const r=e.muted;if(M(t))return;t.muted=r}if(M(t))return;if(e.volume){const r=ct(e.volume,0,1);if(M(t))return;n.volume=r}if(M(t))return;const i=r.get("volume");if(M(t))return;if("number"===typeof i&&(n.volume=ct(i,0,1)),M(t))return;if(e.poster){const r=`url(${e.poster})`;if(M(t))return;et(o,"backgroundImage",r)}if(M(t))return;if(e.autoplay){const r=e.autoplay;if(M(t))return;n.autoplay=r}if(M(t))return;if(e.playsInline){if(M(t))return;if(n.playsInline=!0,M(t))return;n["webkit-playsinline"]=!0}if(M(t))return;if(e.theme){const r=e.cssVar,n=e.theme;if(M(t))return;r["--art-theme"]=n}for(const s in e.cssVar){if(M(t))return;const r=e.cssVar[s];if(M(t))return;t.cssVar(s,r)}if(M(t))return;const a=e.url;M(t)||(t.url=a)}];class Br{constructor(t){if(!M(t)){Vr(t);for(const e of Yr){if(M(t))return;e(t)}}}}const Hr=new WeakMap,jr="art-auto-orientation-fullscreen";function qr(t){if(Hr.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const Ur="art-auto-orientation",Xr=["width","height","transform-origin","transform"];function Gr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return sr(t)&&sr(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=P(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(Ur);r.classList.remove(Ur),n&&(t.isRotate=!1,M(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=B();if(M(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=Xr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(Ur),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;M(t)||(r?o?s(!1):e()&&(i(),i=Ct(n,()=>{o||s(!0)},Number(null!=(l=t.constructor.AUTO_ORIENTATION_TIME)?l:0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(jr),t&&(t.cancelled=!0,qr(t),t.settled&&Hr.get(t.orientation)===t&&Hr.delete(t.orientation))}return P(t).add(o),i=>{var a,s;if(M(t))return;if(!i)return void o();if(n&&!n.cancelled&&Hr.get(n.orientation)===n)return;const l=null==(s=null==(a=r.ownerDocument.defaultView)?void 0:a.screen)?void 0:s.orientation;if("function"!==typeof(null==l?void 0:l.lock)||"function"!==typeof l.unlock||!e())return;const c={orientation:l,cancelled:!1,settled:!1};n=c,Hr.set(l,c);const d=()=>!M(t)&&!c.cancelled&&n===c&&Hr.get(l)===c,u=e=>{c.settled=!0;const o=d();Hr.get(l)===c&&Hr.delete(l),n===c&&(n=void 0),o&&(r.classList.remove(jr),t.notice.show=e)};try{const t=l.lock(l.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{c.settled=!0,d()?r.classList.add(jr):(qr(c),Hr.get(l)===c&&Hr.delete(l))}).catch(u)}catch(p){u(p)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),P(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Kr(t){return t.get("times")||{}}function Zr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||M(t))return()=>{};const s=Ot(".art-auto-playback-last",a),l=Ot(".art-auto-playback-jump",a),c=Ot(".art-auto-playback-close",a);zt(c,r.close);const d=D(a);let u,p=0;const f=()=>{const r=++p;if(null==u||u.dispose(),d.closed||M(t)||p!==r)return;const f=d.child();u=f;const h=()=>u===f&&!f.closed&&!M(t);f.add(()=>{u===f&&(u=void 0,et(a,"display","none"))});const m=le(t).add(()=>{f.dispose()});f.add(()=>{m()});const v=Kr(n)[t.option.id||t.option.url];if(!h())return;if(et(a,"display","none"),!h()||!v||!(v>=o.AUTO_PLAYBACK_MIN))return;if(!h())return;if(et(a,"display","flex"),!h())return;const g=`${e.get("Last Seen")} ${ut(v)}`;if(!h())return;if(s.textContent=g,!h())return;const y=e.get("Jump Play");if(!h())return;if(l.textContent=y,!h())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{h()&&r()});f.add(()=>{t.events.remove(n)})};if(b(c,()=>{et(a,"display","none")}),!h())return;if(b(l,()=>{t.seek=v,h()&&(at(t.play()),h()&&(et(i,"display","none"),h()&&et(a,"display","none")))}),!h())return;let w=()=>{},x=!1;const k=()=>{!x&&h()&&(x=!0,w(),Ct(f,()=>{h()&&et(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",k),w=f.add(()=>{t.off("video:timeupdate",k)}),x&&w()};return()=>{N(t,a,"ready",f),N(t,a,"restart",f)}}(t);return function(t){const{storage:e,constructor:r}=t;_e(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Kr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;M(t)||(o.length>i&&delete n[o[0]],n[a]=s,M(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Kr(e)},clear:()=>e.del("times"),delete(t){const r=Kr(e);return delete r[t],e.set("times",r),r}}}function Jr(t){let e,r=0;return{start:n=>{const o=++r;if(null==e||e.scope.dispose(),o!==r||M(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:le(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{(null==e?void 0:e.active)||q(t.template.$player,"art-fast-forward")}}),Ct(i.scope,()=>{if(e!==i||M(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||M(t))return;t.playbackRate=r,e!==i||i.scope.closed||M(t)||j(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,null==e||e.scope.dispose()}}}function Qr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Jr(t),i=_e(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return U(r,"art-fast-forward")}}}function tn(t,e,r,n){let o;const i=()=>!r.closed&&!M(t),a=t.i18n.get("Lock");if(!i())return()=>{};e.setAttribute("aria-label",a),Mt(r,e),At(r,e,"keydown",t=>{const r=t;i()&&n()&&Pt(r)&&!r.defaultPrevented&&"Escape"===r.key&&(Lt(r),e.click())});const s=n=>{if(i())if(e.setAttribute("aria-pressed",String(n)),n&&!o){const{$player:n,$bottom:a}=t.template,s=a.contains(a.ownerDocument.activeElement)&&n.classList.contains("art-keyboard-focus");o=r.child(),function(t,e){const r=new Map,n=e.hasAttribute("inert"),o=e.getAttribute("aria-hidden"),i=(t,e)=>{"-1"===t.getAttribute("tabindex")&&(null===e?t.removeAttribute("tabindex"):t.setAttribute("tabindex",e))};if(t.add(()=>{for(const[t,e]of r)i(t,e);r.clear(),n||""!==e.getAttribute("inert")||e.removeAttribute("inert"),"true"===e.getAttribute("aria-hidden")&&(null===o?e.removeAttribute("aria-hidden"):e.setAttribute("aria-hidden",o))}),t.closed)return;n||e.setAttribute("inert",""),e.setAttribute("aria-hidden","true");const a=()=>{if(!t.closed){for(const[t,n]of r)e.contains(t)||(i(t,n),r.delete(t));for(const t of e.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]"))r.has(t)||(r.set(t,t.getAttribute("tabindex")),t.setAttribute("tabindex","-1"))}};if(a(),"undefined"!==typeof MutationObserver){const r=new MutationObserver(a);r.observe(e,{childList:!0,subtree:!0}),t.add(()=>{r.disconnect()})}}(o,a),i()&&s&&e.focus({preventScroll:!0})}else if(!n&&o){const t=o;o=void 0,t.dispose()}};return s(n()),s}function en(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return U(n,"art-lock")}function i(){M(t)||(j(n,"art-lock"),M(t)||(t.isLock=!0,M(t)||t.emit("lock",!0)))}function a(){M(t)||(q(n,"art-lock"),M(t)||(t.isLock=!1,M(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=D(e);if(n.closed||M(t))return;const i=zt(e,r.lock);if(n.closed||M(t))return;const a=zt(e,r.unlock);if(n.closed||M(t))return;const s=tn(t,e,n,o);n.closed||M(t)||(o()?(et(i,"display","inline-flex"),n.closed||M(t)||et(a,"display","none")):et(i,"display","none"),N(t,e,"lock",e=>{M(t)||(et(i,"display",e?"inline-flex":"none"),n.closed||M(t)||et(a,"display",e?"none":"inline-flex"),n.closed||M(t)||s(e))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function rn(t){return _e(t)("control",e=>{e?q(t.template.$player,"art-mini-progress-bar"):j(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class nn{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){M(t.art)||!e.miniProgressBar||e.isLive||t.add(rn),!M(t.art)&&e.lock&&k&&t.add(en),M(t.art)||!e.autoPlayback||e.isLive||t.add(Zr),!M(t.art)&&e.autoOrientation&&k&&t.add(Gr),!M(t.art)&&e.fastForward&&k&&!e.isLive&&t.add(Qr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!M(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(M(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(M(t.art))return t;let o=n;const i=yt(t,o);if(M(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return M(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),M(t.art)||vt(t,o,{value:r})),t}(this,t,e)}}const on=new WeakMap;function an(t){return!t.closed&&!on.get(t)}function sn(t){on.set(t,(on.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(on.get(t)||1)-1;r?on.set(t,r):on.delete(t)}}const ln=new WeakMap,cn=new WeakMap,dn=["$parent","$parents","$option","$events","$formatted"];function un(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=ln.get(o);if(!t||!t.owner.active||(null==(e=t.owner.scope)?void 0:e.closed)||!t.option.includes(o))return!1;if(!t.parent)return t.owner.root===t.option;if((null==(r=ln.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function pn(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function fn(t){const e=ln.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function hn(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>xn(t,o)])try{e()}catch(d){d instanceof A?l.push(...d.errors):l.push(d)}if(r.closed||M(t)||(o.push(...i.splice(0)),wn.set(r,o),yn.set(e,r),bn.set(e,n)),a(),l.length)throw new A(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function Cn(t,e,r,n,o,i){const a=i||$n(e);if(!an(a)||M(t))return;const s=t.proxy(r,n,e=>{if(an(a)&&!M(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!an(a)||M(t)?t.events.remove(s):(fn(e).events.push(s),i&&i!==yn.get(e)&&i.add(()=>{const r=fn(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Sn(t,e,r,n){const o=$n(e);if(!an(o)||M(t))return;const i=(...e)=>{if(an(o)&&!M(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Tn(t){var e;const r=null==(e=t.ownerDocument.defaultView)?void 0:e.getComputedStyle(t).visibility;return t.isConnected&&!t.matches(":disabled")&&!t.closest("[inert]")&&"true"!==t.getAttribute("aria-disabled")&&t.getClientRects().length>0&&"hidden"!==r&&"collapse"!==r}function Ln(t){return Array.from(t.querySelectorAll('[tabindex="0"],button,input,select,textarea,a[href],[contenteditable]')).filter(t=>"-1"!==t.getAttribute("tabindex")&&Tn(t))}function Pn(t,e,r=!1){if(!t.show||M(t.art)||!t.active)return;const n=t.cache.get(t.active);if(!n||!an(vn(n)))return;const o=Ln(n),i=n.querySelector(".art-setting-item.art-current"),a=o.find(t=>e===t||(null==e?void 0:e.contains(t)))||(r?o[o.length-1]:o.find(t=>null==i?void 0:i.contains(t))||o.find(t=>!t.classList.contains("art-setting-item-back"))||o[0]);null==a||a.focus({preventScroll:!0}),M(t.art)||null==a||a.scrollIntoView({block:"nearest",inline:"nearest"})}function Mn(t){const e=t.$parent.ownerDocument,r=e.activeElement,n=t.$parent.contains(r);return o=>{n&&!M(t.art)&&(e.activeElement===e.body||e.activeElement===r&&!(null==r?void 0:r.getClientRects().length))&&Pn(t,o)}}function zn(t){const{art:e}=t,r=P(e).child();if(r.closed)return;const n=()=>t.$parent.ownerDocument;let o=!1;const i=()=>{t.show=!1,r.closed||M(e)||t.render()},a=i=>{r.closed||M(e)||(i?n().activeElement===e.controls.setting&&e.template.$player.classList.contains("art-keyboard-focus")&&Pn(t,void 0,o):t.$parent.contains(n().activeElement)&&function(t){const{art:e,$parent:r}=t,n=e.template.$player,o=r.ownerDocument,i=e.controls.setting;!M(e)&&r.contains(o.activeElement)&&(i&&n.contains(i)&&Tn(i)&&i.focus({preventScroll:!0}),(o.activeElement===o.body||r.contains(o.activeElement))&&Dt(e))}(t))};e.on("setting",a),r.add(()=>{e.off("setting",a)}),At(r,e.template.$player,"keydown",r=>{var n,a;const s=r;if(!Pt(s)||s.defaultPrevented||M(e))return;const l=s.target;if(l===e.controls.setting){if("ArrowDown"===s.key||"ArrowUp"===s.key)if(Lt(s),t.show)Pn(t,void 0,"ArrowUp"===s.key);else{o="ArrowUp"===s.key;try{t.show=!0}finally{o=!1}}else"Escape"===s.key&&t.show&&(Lt(s),i());return}if(!t.show||!t.$parent.contains(l))return;if("Escape"===s.key)return Lt(s),void i();const c=l.closest(".art-setting-item");if(!c||l!==c&&!l.matches('button,a[href],[role="button"]'))return;const d=t.active&&t.cache.get(t.active);if(!d)return;const u=null==(n=t.active)?void 0:n.find(t=>t.$item===c);if(!an(vn(d))||u&&!an($n(u)))return void(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End"].includes(s.key)&&Lt(s));const p=Ln(d),f=p.indexOf(l);if(f<0)return;let h;switch(s.key){case"ArrowDown":h=Math.min(f+1,p.length-1);break;case"ArrowUp":h=Math.max(f-1,0);break;case"Home":h=0;break;case"End":h=p.length-1;break;case"ArrowLeft":{const t=d.querySelector(".art-setting-item-back");return Lt(s),void(null==t||t.click())}case"ArrowRight":return Lt(s),void((null==(a=null==u?void 0:u.selector)?void 0:a.length)&&l.click());default:return}Lt(s),void 0!==h&&Pn(t,p[h])});let s=!1;At(r,t.$parent,"focusout",o=>{const a=o.relatedTarget;a&&(t.$parent.contains(a)||a===e.controls.setting)||s||(s=!0,Ct(r,()=>{s=!1,r.closed||M(e)||!t.show||t.$parent.contains(n().activeElement)||n().activeElement===e.controls.setting||i()},0))})}function On(t){var e,r;const{art:n,active:o}=t,{controls:i,constructor:{SETTING_WIDTH:a,SETTING_ITEM_HEIGHT:s},template:{$player:l,$setting:c,$bottom:d}}=n;if(!i.setting||!t.show||!o)return;const u=l.getBoundingClientRect(),p=i.setting.getBoundingClientRect(),f=u.width/l.offsetWidth||1,h=(p.left-u.left+p.width/2)/f-l.clientLeft,m=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:l.clientWidth,containerHeight:l.clientHeight,requestedWidth:(null==(r=null==(e=o[0])?void 0:e.$parent)?void 0:r.width)||a,rows:o.length+(o===t.option?0:1),rowHeight:s,controlCenter:h,bottom:Number.parseFloat(getComputedStyle(c).bottom)||0,padding:Number.parseFloat(getComputedStyle(d).paddingLeft)||0});c.style.height=`${m.height}px`,c.style.width=`${m.width}px`,n.isRotate||k||(h+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const Rn=new WeakMap;function Dn(t){Rn.delete(t)}const In=new WeakMap;function Nn(t,e){e?In.set(t,e):In.delete(t)}function _n(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=In.get(t),i=null==o?void 0:o();for(const a of["html","icon","tooltip"]){const t=null==(e=r.get(a))?void 0:e.value;t instanceof Node&&n.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{var e,a;for(const n of Reflect.ownKeys(t))!r.has(n)&&(null==(e=Object.getOwnPropertyDescriptor(t,n))?void 0:e.configurable)&&Reflect.deleteProperty(t,n);for(const[n,o]of r)Object.defineProperty(t,n,o);null==i||i(),Nn(t,o);for(const{node:t,parent:r,next:o}of n)r?r.insertBefore(t,(null==o?void 0:o.parentNode)===r?o:null):null==(a=t.parentNode)||a.removeChild(t)}}function Wn(t){var e,r;const n=null==(e=t.$item)?void 0:e.querySelector(".art-setting-range");n&&n.setAttribute("aria-label",(null==(r=t.$html)?void 0:r.textContent)||"")}const Fn=new WeakMap;function Vn(t,e,r,n,o,i,a,s){return c(this,null,function*(){try{const l=$n(e),c=$n(i),d=(Fn.get(i)||0)+1;Fn.set(i,d);const u=()=>an(l)&&an(c)&&!M(t.art)&&Fn.get(i)===d;if(null==s||s(),!u())return;const p=yield o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}})}function Yn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const Bn=new WeakMap;function Hn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof A?e.push(...r.errors):e.push(r)}if(e.length)throw new A(e)}function jn(t){var e;null==(e=Bn.get(t))||e()}function qn(t,e){const r=t.find(e.name);if(M(t.art))return r||e;if(!r)return t.add(e);const n=Mn(t);Dn(r),jn(r);const o=_n(r),i=r.$item,a=null==i?void 0:i.parentNode,s=null==i?void 0:i.nextSibling,l=i?Yn(i):void 0,c=t.active,d=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),u=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=An(t.art,e);r&&i.push(r)}for(const t of n)a.push(sn(vn(t)))}catch(l){try{Hn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,Hn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,Hn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>gn(t)),...a]))}}}(t,r);let p=!0,f=!1;const h=()=>{if(!p)return;p=!1;for(const t of u.items)Bn.get(t)===h&&Bn.delete(t);if(M(t.art))return void u.dispose();const e=r.$item;try{Hn([u.resume,()=>{e&&e!==i&&e.remove()},o,()=>null==l?void 0:l(),()=>{a&&i&&a.insertBefore(i,(null==s?void 0:s.parentNode)===a?s:null)},()=>t.format(),()=>{if(f){t.active=c,c&&t.cache.has(c)&&K(t.cache.get(c),"art-current");for(const[e,r,n]of d)t.$parent.style.setProperty(e,r,n)}}]),n(i)}catch(m){console.warn("ArtPlayer setting restore failed:",m)}},m=()=>p&&!M(t.art)&&Bn.get(r)===h;for(const y of u.items)Bn.set(y,h);const v=P(t.art).add(()=>{p=!1;for(const t of u.items)Bn.get(t)===h&&Bn.delete(t);u.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!(null==o?void 0:o.enumerable)||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,m),!m())return r;if(t.format(),!m())return r;if(t.createItem(r,!0),!m())return r;if(f=!0,t.render(),!m())return r;p=!1;for(const t of u.items)Bn.get(t)===h&&Bn.delete(t);return u.dispose(),n(r.$item),r}catch(g){throw m()&&h(),g}finally{v()}}const Un=new WeakMap;function Xn(t,e,r){vt(t,`$${e}`,{configurable:!0,get:()=>r}),vt(t,e,{configurable:!0,get:()=>r.innerHTML,set(n){r.innerHTML="",X(r,n),"html"===e&&Wn(t)}})}function Gn(t,e,r=!1){var n,o;const i=function(t){const e=Bn.get(t);return()=>!e||Bn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";yt(e,"switch")&&(l="switch"),yt(e,"range")&&(l="range"),yt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=P(t)){const n=yn.get(e);(!n||an(n)||n.closed)&&En(t,e);const o=r.child();return yn.set(e,o),bn.set(e,r),wn.set(o,fn(e).events),o.add(()=>{xn(t,wn.get(o))}),o}(t.art,e,vn(a)),p=()=>an(u)&&!M(t.art)&&i();if(!p())return;const f=document.createElement("div");try{if(Nn(e),j(f,"art-setting-item"),et(f,"height",`${d.SETTING_ITEM_HEIGHT}px`),f.dataset.name=e.name||"",f.dataset.value=String(e.value||""),!p())return;const i=zt(f,'
'),h=zt(f,'
'),m=document.createElement("div");switch(j(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;X(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;X(m,t)}else X(m,c.check)}if(X(i,m),!p())return;Xn(e,"icon",m);const v=document.createElement("div");j(v,"art-setting-item-left-text");const g=e.html||"";if(!p())return;X(v,g),X(i,v),Xn(e,"html",v);const y=document.createElement("div");j(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(X(y,b),X(h,y),Xn(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");j(t,"art-setting-item-right-icon");const r=zt(t,c.switchOn),n=zt(t,c.switchOff),o=e.switch;if(!p())return;et(o?n:r,"display","none"),X(h,t),vt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;Nn(e,()=>{const t=i;return()=>{i=t}}),vt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,f.setAttribute("aria-checked",String(Boolean(t))),t?(et(n,"display","none"),et(r,"display",null)):(et(n,"display",null),et(r,"display","none"))}});break}case"range":{const t=document.createElement("div");j(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",X(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!p())return;Reflect.set(r,i,String(t))}j(r,"art-setting-range"),X(h,t),vt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;Nn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),vt(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(null==(o=e.selector)?void 0:o.length){const t=document.createElement("div");j(t,"art-setting-item-right-icon"),X(t,c.arrowRight),X(h,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=$n(e),a=(t,r,n)=>Cn(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>Vn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>Vn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{var o,i;if(null==(o=e.selector)?void 0:o.length)t.render(e.selector);else{if(null==(i=e.$parent)?void 0:i.onSelect)return Vn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&j(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>Vn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,f,l),!p())return;vt(e,"$item",{configurable:!0,get:()=>f}),function(t,e,r,n,o){var i;"range"!==n?r.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")||("switch"===n?(r.setAttribute("role","switch"),r.setAttribute("aria-checked",String(Boolean(e.switch))),r.setAttribute("aria-disabled",String(!e.onSwitch))):"selector"!==n||(null==(i=e.selector)?void 0:i.length)||r.setAttribute("aria-current",String(Boolean(e.default))),Mt(o,r,()=>r.click(),()=>an(o)&&!M(t.art))):Wn(e)}(t,e,f,l,u),r&&(null==s?void 0:s.parentNode)?s.replaceWith(f):X(a,f),e.mounted&&p()&&Ct(u,()=>{var r;if(!M(t.art))try{const n=null==(r=e.mounted)?void 0:r.call(t.art,f,e);Promise.resolve(n).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(n){console.warn("ArtPlayer setting mounted failed:",n)}},0)}catch(h){try{u.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw f.remove(),h}}function Kn(t,e=t.option){var r,n,o,i,a,s;if(M(t.art))return;const l=Mn(t),c=t.cache.get(e);if(c&&!an(vn(c)))return;const d=(Un.get(t)||0)+1;Un.set(t,d);const u=()=>Un.get(t)===d&&!M(t.art),p=t.active,f=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),h=()=>{t.active=p,p&&t.cache.has(p)&&K(t.cache.get(p),"art-current");for(const[e,r,n]of f)t.$parent.style.setProperty(e,r,n)};if(t.active=e,c)try{K(c,"art-current"),t.resize()}catch(m){throw u()&&t.cache.get(e)===c&&!vn(c).closed&&h(),m}else{const a=document.createElement("div");t.cache.set(e,a);const s=function(t,e,r){const n=P(t.art).child();return mn.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,a),l=()=>!s.closed&&!M(t.art)&&t.cache.get(e)===a,c=[];try{if(!l())return;j(a,"art-setting-panel"),a.setAttribute("role","group"),a.setAttribute("aria-label",(null==(o=null==(n=null==(r=e[0])?void 0:r.$parent)?void 0:n.$html)?void 0:o.textContent)||t.art.i18n.get("Settings")),X(t.$parent,a),K(a,"art-current"),(null==(i=e[0])?void 0:i.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=cn.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=P(e).child(),n=(t,n)=>{if(r.closed||M(e))return;const o=(...t)=>{if(!r.closed&&!M(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=F(r,e.controls.setting),o=F(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||M(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this)),zn(this)}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),Sn(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),Sn(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(dt(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),Sn(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{Sn(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){hn(e,t)}check(t){!function(t,e){(null==e?void 0:e.$parent)&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.$item&&t.$item.setAttribute("aria-current",String(t.default)),t.default&&t.$item&&K(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=cn.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;ofn(t).parent},$parents:{get:()=>fn(t).parents},$option:{get:()=>fn(t).option},$events:{get:()=>fn(t).events},$formatted:{get:()=>!0}}),ln.set(t,{parent:r,parents:n,option:o,events:(null==a?void 0:a.events)||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return hn(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){On(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&gn(n)}catch(i){r.push(i)}}try{En(t.art,e)}catch(i){i instanceof A?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new A(r)}(this,t)}remove(t){const e=Mn(this),r=this.find(t);it(r,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Dn(t),jn(t)},[r]);const n=r.$option.indexOf(r);r.$option.splice(n,1);const o=r.$item,i=[];for(const s of[()=>this.inactivate(r),()=>null==o?void 0:o.remove(),()=>this.render()])try{s()}catch(a){a instanceof A?i.push(...a.errors):i.push(a)}if(i.length)throw new A(i);e()}update(t){return qn(this,t)}add(t,e=this.option){var r;if(M(this.art))return t;let n=!1;this.traverse(e=>{n||(n=e===t)});const o=e.length,i=n?void 0:function(t){const e={};Rn.set(t,e);const r=()=>Rn.get(t)===e;return{current:r,finish(){r()&&Rn.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(M(this.art)||i&&!i.current())throw s;if(e[o]===t&&e.splice(o,1),!n&&a){try{this.inactivate(t)}catch(l){console.warn("ArtPlayer setting cleanup failed:",l)}null==(r=t.$item)||r.remove()}throw s}finally{null==i||i.finish()}return t}createHeader(t){!function(t,e){var r;if(!t.cache.has(e.$option))return;const n=t.cache.get(e.$option),{icons:{arrowLeft:o},constructor:{SETTING_ITEM_HEIGHT:i}}=t.art,a=document.createElement("div");et(a,"height",`${i}px`),j(a,"art-setting-item"),j(a,"art-setting-item-back");const s=zt(a,'
'),l=document.createElement("div");j(l,"art-setting-item-left-icon"),X(l,o),X(s,l),X(s,e.$parent.html),Cn(t.art,e.$parent,a,"click",()=>t.render(e.$parents),vn(n));const c=vn(n);a.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")||Mt(c,a,()=>a.click(),()=>an(c)&&!M(t.art)),a.setAttribute("aria-label",`${t.art.i18n.get("Back")}: ${(null==(r=a.textContent)?void 0:r.trim())||""}`),X(n,a)}(this,t)}createItem(t,e=!1){Gn(this,t,e)}render(t=this.option){Kn(this,t)}}class Qn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch(e){return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch(r){this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch(e){delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch(t){this.settings={}}}}const to='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:opacity var(--art-transition-duration) ease,transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel,.art-control-volume:focus-within .art-volume-panel{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:focus-within .art-mini-close,.art-mini-popup:hover .art-mini-state,.art-mini-popup:focus-within .art-mini-state{opacity:1}.art-mini-popup [role=button]:focus-visible{outline:2px solid #fff;outline-offset:-2px}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-layer-lock{display:flex}.art-video-player.art-lock:not(.art-control-show) .art-layer-lock{opacity:0;pointer-events:none}.art-video-player.art-lock:not(.art-control-show) .art-layer-lock:focus-within{opacity:1;pointer-events:auto}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:opacity var(--art-transition-duration) ease,transform var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover:not(.art-selector-dismissed) .art-selector-list,.art-control-selector.art-selector-open .art-selector-list{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}.art-video-player [tabindex]:focus-visible,.art-video-player input:focus-visible,.art-video-player button:focus-visible,.art-video-player a:focus-visible{outline:2px solid currentColor;outline-offset:-2px}.art-video-player.art-keyboard-focus :focus{outline:2px solid currentColor;outline-offset:-2px}.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom{opacity:1}.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-controls,.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-progress{transform:translateY(0)}';class eo{constructor(t){var e;this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=null==(e=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope))?void 0:e.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}run(t){return c(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const ro=new WeakMap;function no(t){return ro.get(t)}function oo(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const io=Kt;class ao extends io{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=P(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return ro.set(t,n),r.add(()=>{oo(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){var t,e;return null==(e=null==(t=this.art.template.$video)?void 0:t.textTracks)?void 0:e[0]}get activeCues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.activeCues)||[])}get cues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.cues)||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?rt(r,t):et(r,t,e)}update(){!function(t){const e=no(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?mt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return c(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=l(s(s({},o.subtitle),e),{url:t}),a=no(this),c=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===c&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=no(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(c)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const f=n.track;n.track=u,t.destroyEvent=c,s.onload=null,s.onerror=null,p=!0;try{null==f||f.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&oo(n)}}catch(f){if(p)throw f;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw f;throw a.$track=s,l&&l.insertBefore(s,(null==c?void 0:c.parentNode)===l?c:null),f}}(this,t,e)}init(t){return c(this,null,function*(){const e=no(this),r=function(t){const e=t.request,r=new eo(t.scope);return t.request=r,t.revision+=1,null==e||e.cancel(),r}(e),{notice:n,template:{$subtitle:o}}=this.art;return r.run(()=>c(this,null,function*(){if(!this.textTrack)return null;if(h(t,Xt.subtitle),!t.url)return;let i;this.option=t,this.style(t.style);try{if(!r.active)return;const n=yield fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const a=yield n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||st(e.url)){case"srt":return{vtt:e.onVttLoad(xt(r))};case"ass":return{vtt:e.onVttLoad($t(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=kt(s.vtt);if(!r.active)return;o.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return i&&(e.ownedURL=i,i=void 0),l}catch(a){if(!r.active)return;throw o.innerHTML="",n.show=a,a}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}}))})}}const so=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${m}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class lo{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=H(e.container),it(this.$container,`No container element found by ${e.container}`)),it(V(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();it("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),it(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=T.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=L(t);o.rollback=r,T.set(e,t),o.releaseContainer=()=>{T.get(e)===t&&T.delete(e)}}(t,this.$container,Yn(this.$container)),function(t,e,r){const n=L(t),o=n.mountingTemplate;n.mountingTemplate=e;try{r()}finally{n.mountingTemplate=o}}(t,this,()=>{this.$container.dataset.artId=String(t.id),this.init()})}static get html(){return so}query(t){return H(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=lo.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);if(M(this.art))return;!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),Z(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&j(this.$player,"art-backdrop"),k&&j(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":j(this.$player,"art-destroy")}}const co=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class uo{on(t,e,r){const n=this.e||(this.e={});let o=co(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(co(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=co(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new lo(this),P(this).closed)return;if(this.events=new Fe(this),P(this).closed)return;if(this.storage=new Qn,P(this).closed)return;if(this.icons=new Ge(this),P(this).closed)return;if(this.i18n=new Ue(this),P(this).closed)return;if(this.notice=new ir(this),P(this).closed)return;if(this.player=new Br(this),P(this).closed)return;if(this.layers=new tr(this),P(this).closed)return;if(this.controls=new Pe(this),P(this).closed)return;if(this.contextmenu=new oe(this),P(this).closed)return;if(this.subtitle=new ao(this),P(this).closed)return;if(this.info=new Qe(this),P(this).closed)return;if(this.loading=new er(this),P(this).closed)return;if(this.hotkey=new je(this),P(this).closed)return;if(this.mask=new rr(this),P(this).closed)return;if(this.setting=new Jn(this),P(this).closed)return;if(this.plugins=new nn(this),P(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),ho.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${ho.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=L(t);return e.rollback=void 0,!e.scope.closed})(this)&&fo.push(this)}catch(r){try{z(this,fo,!0,ho.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return fo}static get version(){return m}static get config(){return E}static get utils(){return Et}static get scheme(){return Xt}static get Emitter(){return uo}static get validator(){return h}static get kindOf(){return h.kindOf}static get html(){return lo.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:b?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:null==navigator?void 0:navigator.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){z(this,fo,t,ho.REMOVE_SRC_WHEN_DESTROY)}}var mo,vo;return ho.STYLE=to,ho.DEBUG=!1,ho.CONTEXTMENU=!0,ho.NOTICE_TIME=2e3,ho.SETTING_WIDTH=250,ho.SETTING_ITEM_WIDTH=200,ho.SETTING_ITEM_HEIGHT=35,ho.RESIZE_TIME=200,ho.SCROLL_TIME=200,ho.SCROLL_GAP=50,ho.AUTO_PLAYBACK_MAX=10,ho.AUTO_PLAYBACK_MIN=5,ho.AUTO_PLAYBACK_TIMEOUT=3e3,ho.RECONNECT_TIME_MAX=5,ho.RECONNECT_SLEEP_TIME=1e3,ho.CONTROL_HIDE_TIME=3e3,ho.DBCLICK_TIME=300,ho.DBCLICK_FULLSCREEN=!0,ho.MOBILE_DBCLICK_PLAY=!0,ho.MOBILE_CLICK_PLAY=!1,ho.AUTO_ORIENTATION_TIME=200,ho.INFO_LOOP_TIME=1e3,ho.FAST_FORWARD_VALUE=3,ho.FAST_FORWARD_TIME=1e3,ho.TOUCH_MOVE_RATIO=.5,ho.VOLUME_STEP=.1,ho.SEEK_STEP=5,ho.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],ho.ASPECT_RATIO=["default","4:3","16:9"],ho.FLIP=["normal","horizontal","vertical"],ho.FULLSCREEN_WEB_IN_BODY=!0,ho.LOG_VERSION=!0,ho.USE_RAF=!1,ho.REMOVE_SRC_WHEN_DESTROY=!0,mo=ho,vo=to,$&&(window.Artplayer=mo,v("artplayer-style",vo),setTimeout(()=>{mo.LOG_VERSION&&console.log(`%c ArtPlayer %c ${mo.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),ho}); diff --git a/docs/compiled/artplayer.mjs b/docs/compiled/artplayer.mjs index 637498faf..4cbf30f51 100644 --- a/docs/compiled/artplayer.mjs +++ b/docs/compiled/artplayer.mjs @@ -1031,6 +1031,155 @@ const utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert userAgent, vttToBlob }, Symbol.toStringTag, { value: "Module" })); +function listen(scope, target, name, callback, options = {}) { + const { capture = false, once = false, signal } = options; + if (scope.closed || signal?.aborted) + return () => { + }; + let release = () => { + }; + function listener(event) { + if (once) + release(); + if (scope.closed) + return; + if (typeof callback === "function") + callback.call(this, event); + else + callback.handleEvent(event); + } + target.addEventListener(name, listener, options); + release = scope.add(() => { + try { + target.removeEventListener(name, listener, capture); + } finally { + signal?.removeEventListener("abort", release); + } + }); + signal?.addEventListener("abort", release, { once: true }); + return release; +} +function timeout(scope, callback, delay) { + if (scope.closed) + return () => { + }; + let pending2 = true; + let release = () => { + }; + const timer = setTimeout(() => { + if (!pending2) + return; + release(); + if (!scope.closed) + callback(); + }, delay); + release = scope.add(() => { + pending2 = false; + clearTimeout(timer); + }); + return release; +} +function animationFrame(scope, callback) { + if (scope.closed) + return () => { + }; + let pending2 = true; + let release = () => { + }; + const frame = requestAnimationFrame((time2) => { + if (!pending2) + return; + release(); + if (!scope.closed) + callback(time2); + }); + release = scope.add(() => { + pending2 = false; + cancelAnimationFrame(frame); + }); + return release; +} +function requestController(scope) { + if (typeof AbortController === "undefined") + return void 0; + const controller = new AbortController(); + scope.add(() => { + controller.abort(); + }); + return controller; +} +function wait(scope, delay = 0) { + if (scope.closed) + return Promise.resolve(false); + return new Promise((resolve) => { + let completed = false; + let release = () => { + }; + const timer = setTimeout(() => { + completed = true; + release(); + resolve(true); + }, delay); + release = scope.add(() => { + clearTimeout(timer); + if (!completed) + resolve(false); + }); + }); +} +const handled = /* @__PURE__ */ new WeakSet(); +function claimKey(event) { + handled.add(event); + event.preventDefault(); +} +function isClaimedKey(event) { + return handled.has(event); +} +function plainKey(event) { + return !event.altKey && !event.ctrlKey && !event.metaKey && !event.isComposing && event.keyCode !== 229; +} +function keyboardButton(scope, element, activate = () => element.click(), active2 = () => true) { + if (scope.closed) + return; + if (!element.hasAttribute("role")) + element.setAttribute("role", "button"); + if (!element.hasAttribute("tabindex")) + element.tabIndex = 0; + let space = false; + const enabled = () => active2() && element.getAttribute("aria-disabled") !== "true" && !element.hasAttribute("disabled"); + const own = (event) => (event.composedPath()[0] || event.target) === element; + listen(scope, element, "keydown", (value) => { + const event = value; + if (!own(event) || !plainKey(event) || event.defaultPrevented) + return; + if (event.key === "Enter") { + claimKey(event); + if (!event.repeat && enabled()) + activate(); + } else if (event.key === " ") { + claimKey(event); + if (!event.repeat && enabled()) + space = true; + } + }); + listen(scope, element, "keyup", (value) => { + const event = value; + if (event.key !== " ") + return; + const armed = space; + space = false; + if (armed && own(event) && plainKey(event) && !event.defaultPrevented && enabled() && element.ownerDocument.activeElement === element) { + claimKey(event); + activate(); + } + }); + listen(scope, element, "blur", () => { + space = false; + }); + scope.add(() => { + space = false; + }); +} function renderEntry(element, parent, kind, name, id2, option) { addClass(element, `art-${kind}`); addClass(element, `art-${kind}-${name}`); @@ -1054,6 +1203,63 @@ function appendElement(parent, child) { function queryElement(selector, parent) { return parent.querySelector(selector); } +const owned = /* @__PURE__ */ new WeakSet(); +function focusPlayer(art) { + const player = art.template.$player; + if (isClosing(art) || !player.isConnected) + return; + if (!player.hasAttribute("tabindex")) { + player.setAttribute("tabindex", "-1"); + if (!owned.has(player)) { + owned.add(player); + getScope(art).add(() => { + owned.delete(player); + if (player.getAttribute("tabindex") === "-1") + player.removeAttribute("tabindex"); + }); + } + } + player.focus({ preventScroll: true }); +} +const pending$1 = /* @__PURE__ */ new WeakSet(); +const focusable = "[tabindex],button,input,select,textarea,a[href],[contenteditable]"; +function targetIn(element) { + const targets = [element, ...element.querySelectorAll(focusable)]; + return targets.find((target) => { + if (!target.matches(focusable) || target.tabIndex < 0 || target.matches(":disabled") || target.closest("[inert]") || target.getAttribute("aria-disabled") === "true" || !target.getClientRects().length) + return false; + const style = target.ownerDocument.defaultView?.getComputedStyle(target); + return style?.visibility !== "hidden" && style?.visibility !== "collapse"; + }); +} +function captureComponentFocus(owner, element, replacement) { + const doc = element?.ownerDocument; + const focused = doc?.activeElement; + if (!["control", "contextmenu"].includes(owner.name ?? "") || pending$1.has(owner) || !element || !doc || !focused || !element.contains(focused)) + return () => { + }; + const player = owner.art.template.$player; + const controls = Array.from(player.querySelectorAll(`.art-${owner.name}`)); + const index = controls.indexOf(element); + const neighbors = [...controls.slice(index + 1), ...controls.slice(0, index).reverse()]; + pending$1.add(owner); + return () => { + pending$1.delete(owner); + if (isClosing(owner.art) || !player.isConnected || doc.activeElement !== doc.body) + return; + const next = replacement ? owner.cache.get(replacement)?.$ref : void 0; + for (const candidate of [...next ? [next] : [], ...neighbors]) { + if (!player.contains(candidate)) + continue; + const target = targetIn(candidate); + if (target) { + target.focus({ preventScroll: true }); + return; + } + } + focusPlayer(owner.art); + }; +} const a = "array"; const b = "boolean"; const s = "string"; @@ -1228,6 +1434,9 @@ class Component { if (scope.closed) return; if (option.click) { + const actionable = this.name === "control" && !option.selector || this.name === "contextmenu" && !$ref.querySelector("[data-value]"); + if (actionable && !$ref.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")) + keyboardButton(scope, $ref); const cleanup = this.art.events.proxy($ref, "click", (event) => { if (scope.closed) return; @@ -1269,6 +1478,7 @@ class Component { const item = this.cache.get(name); if (removing.has(item)) return; + const restoreFocus = captureComponentFocus(this, item.$ref); removing.add(item); try { if (item.option.beforeUnmount) @@ -1284,15 +1494,21 @@ class Component { } } finally { removing.delete(item); + restoreFocus(); } } update(option) { - if (this.cache.has(option.name)) { - const item = this.cache.get(option.name); - option = Object.assign(item.option, option); - this.remove(option.name); + const restoreFocus = captureComponentFocus(this, this.cache.get(option.name)?.$ref, option.name); + try { + if (this.cache.has(option.name)) { + const item = this.cache.get(option.name); + option = Object.assign(item.option, option); + this.remove(option.name); + } + return this.add(option); + } finally { + restoreFocus(); } - return this.add(option); } } function assignAlias(owner, name, value) { @@ -1302,6 +1518,22 @@ function assignAlias(owner, name, value) { else aliases[name] = value; } +function updateChoices(panel) { + for (const item of panel.querySelectorAll("[data-value]")) + item.setAttribute("aria-pressed", String(item.classList.contains("art-current"))); +} +function keyboardChoices(panel, label) { + const scope = entryScope(panel); + if (scope.closed) + return; + panel.setAttribute("role", "group"); + panel.setAttribute("aria-label", label); + for (const item of panel.querySelectorAll("[data-value]")) { + keyboardButton(scope, item); + item.setAttribute("aria-label", `${label}: ${item.textContent?.trim() ?? ""}`); + } + updateChoices(panel); +} function aspectRatio$2(option) { return (art) => { const { @@ -1311,9 +1543,10 @@ function aspectRatio$2(option) { const html2 = ASPECT_RATIO.map( (item) => `${item === "default" ? i18n.get("Default") : item}` ).join(""); + const label = i18n.get("Aspect Ratio"); return { ...option, - html: `${i18n.get("Aspect Ratio")}: ${html2}`, + html: `${label}: ${html2}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : void 0; if (value) { @@ -1327,10 +1560,12 @@ function aspectRatio$2(option) { if ($default) { inverseClass($default, "art-current"); } + keyboardChoices($panel, label); on("aspectRatio", (value) => { const $current = Array.from($panel.querySelectorAll("span")).find((item) => item.dataset.value === value); if ($current) { inverseClass($current, "art-current"); + updateChoices($panel); } }); } @@ -1353,9 +1588,10 @@ function flip$2(option) { constructor: { FLIP } } = art; const html2 = FLIP.map((item) => `${i18n.get(capitalize(item))}`).join(""); + const label = i18n.get("Video Flip"); return { ...option, - html: `${i18n.get("Video Flip")}: ${html2}`, + html: `${label}: ${html2}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : void 0; if (value) { @@ -1369,10 +1605,12 @@ function flip$2(option) { if ($default) { inverseClass($default, "art-current"); } + keyboardChoices($panel, label); on("flip", (value) => { const $current = Array.from($panel.querySelectorAll("span")).find((item) => item.dataset.value === value); if ($current) { inverseClass($current, "art-current"); + updateChoices($panel); } }); } @@ -1389,6 +1627,158 @@ function info(option) { } }); } +const origins$1 = /* @__PURE__ */ new WeakMap(); +function setOverlayOrigin(overlay, origin) { + if (origin) + origins$1.set(overlay, origin); + else + origins$1.delete(overlay); +} +function resolveFocusOrigin(target) { + const visited = /* @__PURE__ */ new Set(); + let current2 = target; + while (!visited.has(current2)) { + visited.add(current2); + let element = current2; + let origin; + while (element && !origin) { + origin = origins$1.get(element); + element = element.parentElement; + } + if (!origin) + return current2; + current2 = origin; + } + return target; +} +function editable$1(target) { + const element = target; + return !!element && (["INPUT", "TEXTAREA", "SELECT"].includes(element.tagName) || element.isContentEditable); +} +function available$1(element) { + const visibility = element.ownerDocument.defaultView?.getComputedStyle(element).visibility; + return element.isConnected && !element.matches(":disabled") && !element.closest("[inert]") && element.getAttribute("aria-disabled") !== "true" && element.getClientRects().length > 0 && visibility !== "hidden" && visibility !== "collapse"; +} +function contextmenuKeyboard(menu, open) { + const { art } = menu; + const { $player, $contextmenu } = art.template; + const scope = entryScope($contextmenu); + const active2 = () => !scope.closed && !isClosing(art); + let origin; + let hadFocus = false; + let prefix = ""; + let typedAt = 0; + const capture = () => { + const focused = $player.ownerDocument.activeElement; + origin = focused && $player.contains(focused) ? resolveFocusOrigin(focused) : $player; + setOverlayOrigin($contextmenu, origin); + }; + const targets = () => Array.from($contextmenu.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]")).filter((element) => element.tabIndex >= 0 && available$1(element)); + const label = art.i18n.get("Context Menu"); + if (!active2()) + return { pointer: () => false }; + $contextmenu.setAttribute("role", "group"); + $contextmenu.setAttribute("aria-label", label); + const changed = (show) => { + if (!active2()) + return; + if (show) { + if (!$contextmenu.contains($player.ownerDocument.activeElement)) + capture(); + return; + } + const focused = $player.ownerDocument.activeElement; + const restore = $contextmenu.contains(focused) || hadFocus && focused === $player.ownerDocument.body; + const previous = origin; + origin = void 0; + hadFocus = false; + prefix = ""; + setOverlayOrigin($contextmenu); + if (!restore) + return; + if (previous && $player.contains(previous) && available$1(previous)) + previous.focus({ preventScroll: true }); + if ($player.ownerDocument.activeElement === $player.ownerDocument.body || $contextmenu.contains($player.ownerDocument.activeElement)) + focusPlayer(art); + }; + art.on("contextmenu", changed); + scope.add(() => { + art.off("contextmenu", changed); + setOverlayOrigin($contextmenu); + }); + listen(scope, $contextmenu, "focusin", () => { + hadFocus = true; + }); + let pending2 = false; + listen(scope, $contextmenu, "focusout", (input) => { + if ($contextmenu.contains(input.relatedTarget) || pending2) + return; + pending2 = true; + timeout(scope, () => { + pending2 = false; + if (active2() && menu.show && !$contextmenu.contains($player.ownerDocument.activeElement)) + menu.show = false; + }, 0); + }); + listen(scope, $player, "keydown", (input) => { + const event = input; + if (!active2() || !plainKey(event) || event.defaultPrevented) + return; + const opening = event.key === "ContextMenu" || event.key === "F10" && event.shiftKey; + if (opening && art.constructor.CONTEXTMENU && !editable$1(event.target)) { + claimKey(event); + capture(); + const rect = event.target.getBoundingClientRect(); + open(rect.left, rect.bottom); + if (active2() && menu.show) + targets()[0]?.focus({ preventScroll: true }); + return; + } + if (!menu.show || !$contextmenu.contains(event.target)) + return; + if (event.key === "Escape") { + claimKey(event); + menu.show = false; + return; + } + if (event.key === "Tab") { + menu.show = false; + return; + } + if (editable$1(event.target)) + return; + const items = targets(); + const index = items.indexOf(event.target); + let target; + if (event.key === "ArrowDown" || event.key === "ArrowRight") { + target = items[(index + 1) % items.length]; + } else if (event.key === "ArrowUp" || event.key === "ArrowLeft") { + target = items[(index + items.length - 1) % items.length]; + } else if (event.key === "Home") { + target = items[0]; + } else if (event.key === "End") { + target = items[items.length - 1]; + } else if (event.key.length === 1 && event.key !== " ") { + const key = event.key.toLowerCase(); + prefix = Date.now() - typedAt > 700 ? key : prefix + key; + typedAt = Date.now(); + const search = [...prefix].every((letter) => letter === key) ? key : prefix; + target = [...items.slice(index + 1), ...items.slice(0, index + 1)].find((item) => (item.getAttribute("aria-label") || item.textContent || "").trim().toLowerCase().startsWith(search)); + } else { + return; + } + claimKey(event); + target?.focus({ preventScroll: true }); + }); + return { + pointer(event) { + if (!active2() || !art.constructor.CONTEXTMENU || editable$1(event.target)) + return false; + capture(); + return true; + } + }; +} function playbackRate$2(option) { return (art) => { const { @@ -1398,9 +1788,10 @@ function playbackRate$2(option) { const html2 = PLAYBACK_RATE.map( (item) => `${item === 1 ? i18n.get("Normal") : item.toFixed(1)}` ).join(""); + const label = i18n.get("Play Speed"); return { ...option, - html: `${i18n.get("Play Speed")}: ${html2}`, + html: `${label}: ${html2}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : void 0; if (value) { @@ -1413,18 +1804,33 @@ function playbackRate$2(option) { const $default = query('[data-value="1"]', $panel); if ($default) inverseClass($default, "art-current"); + keyboardChoices($panel, label); on("video:ratechange", () => { const $current = Array.from($panel.querySelectorAll("span")).find( (item) => Number(item.dataset.value) === art.playbackRate ); if ($current) { inverseClass($current, "art-current"); + updateChoices($panel); } }); } }; }; } +function positionContextmenu(art, mouseX, mouseY) { + const { $player, $contextmenu } = art.template; + const { height: cHeight, width: cWidth, left: cLeft, top: cTop } = getRect($player); + const { height: mHeight, width: mWidth } = getRect($contextmenu); + let menuLeft = mouseX - cLeft; + let menuTop = mouseY - cTop; + if (mouseX + mWidth > cLeft + cWidth) + menuLeft = cWidth - mWidth; + if (mouseY + mHeight > cTop + cHeight) + menuTop = cHeight - mHeight; + if (!isClosing(art)) + setStyles($contextmenu, { top: `${menuTop}px`, left: `${menuLeft}px` }); +} function version(option) { return { ...option, @@ -1492,27 +1898,21 @@ class Contextmenu extends Component { for (let index = 0; index < option.contextmenu.length; index++) { this.add(option.contextmenu[index]); } + if (isClosing(this.art)) + return; + releaseEntry($contextmenu); + const scope = ownEntry(this.art, $contextmenu); + const open = (x, y) => { + this.show = true; + if (!scope.closed && !isClosing(this.art) && this.show) + positionContextmenu(this.art, x, y); + }; + const keyboard = contextmenuKeyboard(this, open); proxy($player, "contextmenu", (event) => { - if (!this.art.constructor.CONTEXTMENU) + if (!keyboard.pointer(event)) return; event.preventDefault(); - this.show = true; - const mouseX = event.clientX; - const mouseY = event.clientY; - const { height: cHeight, width: cWidth, left: cLeft, top: cTop } = getRect($player); - const { height: mHeight, width: mWidth } = getRect($contextmenu); - let menuLeft = mouseX - cLeft; - let menuTop = mouseY - cTop; - if (mouseX + mWidth > cLeft + cWidth) { - menuLeft = cWidth - mWidth; - } - if (mouseY + mHeight > cTop + cHeight) { - menuTop = cHeight - mHeight; - } - setStyles($contextmenu, { - top: `${menuTop}px`, - left: `${menuLeft}px` - }); + open(event.clientX, event.clientY); }); proxy($player, "click", (event) => { if (!includeFromEvent(event, $contextmenu)) { @@ -1524,101 +1924,51 @@ class Contextmenu extends Component { }); } } -function listen(scope, target, name, callback, options = {}) { - const { capture = false, once = false, signal } = options; - if (scope.closed || signal?.aborted) - return () => { - }; - let release = () => { +function focusVisibility(scope, root, show) { + let keyboard = true; + let document2; + let documentScope; + const focused = () => !scope.closed && keyboard && root.contains(root.ownerDocument.activeElement); + const update = () => { + const visible = focused(); + const previous = root.classList.contains("art-keyboard-focus"); + root.classList.toggle("art-keyboard-focus", visible); + if (visible && !previous) + show(); }; - function listener(event) { - if (once) - release(); - if (scope.closed) - return; - if (typeof callback === "function") - callback.call(this, event); - else - callback.handleEvent(event); - } - target.addEventListener(name, listener, options); - release = scope.add(() => { - try { - target.removeEventListener(name, listener, capture); - } finally { - signal?.removeEventListener("abort", release); - } - }); - signal?.addEventListener("abort", release, { once: true }); - return release; -} -function timeout(scope, callback, delay) { - if (scope.closed) - return () => { - }; - let pending2 = true; - let release = () => { + const key = () => { + keyboard = true; + update(); }; - const timer = setTimeout(() => { - if (!pending2) - return; - release(); - if (!scope.closed) - callback(); - }, delay); - release = scope.add(() => { - pending2 = false; - clearTimeout(timer); - }); - return release; -} -function animationFrame(scope, callback) { - if (scope.closed) - return () => { - }; - let pending2 = true; - let release = () => { + const pointer = () => { + keyboard = false; + update(); }; - const frame = requestAnimationFrame((time2) => { - if (!pending2) + const bindDocument = () => { + if (document2 === root.ownerDocument) return; - release(); - if (!scope.closed) - callback(time2); + documentScope?.dispose(); + document2 = root.ownerDocument; + documentScope = scope.child(); + listen(documentScope, document2, "keydown", key, { capture: true }); + listen(documentScope, document2, "mousedown", pointer, { capture: true }); + listen(documentScope, document2, "touchstart", pointer, { capture: true, passive: true }); + }; + bindDocument(); + listen(scope, root, "keydown", key, { capture: true }); + listen(scope, root, "mousedown", pointer, { capture: true }); + listen(scope, root, "touchstart", pointer, { capture: true, passive: true }); + listen(scope, root, "focusin", () => { + bindDocument(); + update(); }); - release = scope.add(() => { - pending2 = false; - cancelAnimationFrame(frame); + listen(scope, root, "focusout", () => { + root.classList.remove("art-keyboard-focus"); }); - return release; -} -function requestController(scope) { - if (typeof AbortController === "undefined") - return void 0; - const controller = new AbortController(); scope.add(() => { - controller.abort(); - }); - return controller; -} -function wait(scope, delay = 0) { - if (scope.closed) - return Promise.resolve(false); - return new Promise((resolve) => { - let completed = false; - let release = () => { - }; - const timer = setTimeout(() => { - completed = true; - release(); - resolve(true); - }, delay); - release = scope.add(() => { - clearTimeout(timer); - if (!completed) - resolve(false); - }); + root.classList.remove("art-keyboard-focus"); }); + return focused; } function airplay$1(option) { return (art) => ({ @@ -1627,6 +1977,7 @@ function airplay$1(option) { mounted: ($control) => { const { proxy } = controlEvents(art, $control); const { icons } = art; + keyboardButton(entryScope($control), $control); appendElement($control, icons.airplay); proxy($control, "click", () => art.airplay()); } @@ -1639,6 +1990,7 @@ function fullscreen(option) { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control); const { icons, i18n } = art; + keyboardButton(entryScope($control), $control); const $fullscreenOn = appendElement($control, icons.fullscreenOn); const $fullscreenOff = appendElement($control, icons.fullscreenOff); setStyle($fullscreenOff, "display", "none"); @@ -1666,6 +2018,7 @@ function fullscreenWeb(option) { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control); const { icons, i18n } = art; + keyboardButton(entryScope($control), $control); const $fullscreenWebOn = appendElement($control, icons.fullscreenWebOn); const $fullscreenWebOff = appendElement($control, icons.fullscreenWebOff); setStyle($fullscreenWebOff, "display", "none"); @@ -1693,6 +2046,7 @@ function pip$1(option) { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control); const { icons, i18n } = art; + keyboardButton(entryScope($control), $control); appendElement($control, icons.pip); proxy($control, "click", () => { art.pip = !art.pip; @@ -1711,6 +2065,7 @@ function playAndPause(option) { const { icons, i18n } = art; const $play = appendElement($control, icons.play); const $pause = appendElement($control, icons.pause); + keyboardButton(entryScope($control), $control, () => (art.playing ? $pause : $play).click()); tooltip($play, i18n.get("Play")); tooltip($pause, i18n.get("Pause")); proxy($play, "click", () => { @@ -1720,10 +2075,12 @@ function playAndPause(option) { art.pause(); }); function showPlay() { + $control.setAttribute("aria-label", i18n.get("Play")); setStyle($play, "display", "flex"); setStyle($pause, "display", "none"); } function showPause() { + $control.setAttribute("aria-label", i18n.get("Pause")); setStyle($play, "display", "none"); setStyle($pause, "display", "flex"); } @@ -1892,6 +2249,165 @@ function installProgressInteractions(art, $control) { }); } } +const directions = /* @__PURE__ */ new Map([["ArrowRight", 1], ["ArrowUp", 1], ["ArrowLeft", -1], ["ArrowDown", -1], ["PageUp", 10], ["PageDown", -10]]); +function keyboardSlider(scope, element, label, read, write, orientation = "horizontal") { + const valid = (range) => [range.min, range.max, range.value, range.step].every(Number.isFinite) && range.max > range.min && range.step > 0; + const clamp2 = (value, range) => Math.min(range.max, Math.max(range.min, value)); + const update = () => { + if (scope.closed) + return; + const range = read(); + const enabled = valid(range); + const value = enabled ? clamp2(range.value, range) : 0; + element.setAttribute("aria-disabled", String(!enabled)); + element.setAttribute("aria-valuemin", String(enabled ? range.min : 0)); + element.setAttribute("aria-valuemax", String(enabled ? range.max : 0)); + element.setAttribute("aria-valuenow", String(value)); + element.setAttribute("aria-valuetext", range.text(value)); + }; + if (scope.closed) + return update; + element.setAttribute("role", "slider"); + element.tabIndex = 0; + element.setAttribute("aria-label", label); + element.setAttribute("aria-orientation", orientation); + listen(scope, element, "keydown", (value) => { + const event = value; + if ((event.composedPath()[0] || event.target) !== element || !plainKey(event) || event.defaultPrevented) + return; + const direction = directions.get(event.key); + if (direction === void 0 && event.key !== "Home" && event.key !== "End") + return; + claimKey(event); + const range = read(); + if (!valid(range)) { + update(); + return; + } + const next = event.key === "Home" ? range.min : event.key === "End" ? range.max : clamp2(range.value, range) + direction * range.step; + write(clamp2(next, range)); + update(); + }); + update(); + return update; +} +const revisions = /* @__PURE__ */ new WeakMap(); +function positionRevision(art) { + return revisions.get(art) || 0; +} +function advancePosition(art) { + revisions.set(art, positionRevision(art) + 1); +} +const POSITION_TOLERANCE = 0.05; +function positionRestoration(art, target, active2) { + let expected; + let observedSeek = false; + let corrected = false; + let manual = false; + let revision = positionRevision(art); + const manualPosition = () => manual || positionRevision(art) !== revision; + const seeking = () => !!art.template?.$video?.seeking; + return { + restore(write = () => { + art.currentTime = target; + }) { + if (!active2() || manualPosition()) + return; + const previousRevision = positionRevision(art); + write(); + revision = positionRevision(art); + if (revision > previousRevision + 1) + manual = true; + if (!active2()) + return; + expected = art.currentTime; + if (!active2() || manualPosition()) + return; + observedSeek = seeking(); + }, + manual() { + manual = true; + }, + ready() { + if (!active2() || seeking()) + return false; + const missed = expected !== void 0 && Math.abs(art.currentTime - expected) > POSITION_TOLERANCE; + if (!manualPosition() && observedSeek && !corrected && expected !== void 0 && missed) { + corrected = true; + if (!active2()) + return false; + art.currentTime = expected; + } + return active2() && !seeking(); + } + }; +} +function installProgressKeyboard(art, element) { + const scope = entryScope(element); + const { on } = controlEvents(art, element); + let revision = 0; + let pending2; + const update = keyboardSlider(scope, element, art.i18n.get("Progress"), () => ({ + min: 0, + max: art.duration, + value: art.currentTime, + step: art.constructor.SEEK_STEP, + text: (value) => `${secondToTime(value)} / ${secondToTime(Number.isFinite(art.duration) && art.duration > 0 ? art.duration : 0)}` + }), (value) => { + const action = ++revision; + pending2?.dispose(); + const operation = scope.child(); + pending2 = operation; + const releaseSource = getSourceScope(art).add(() => { + operation.dispose(); + }); + operation.add(() => { + releaseSource(); + }); + operation.add(() => { + if (pending2 === operation) + pending2 = void 0; + }); + const sourceActive = captureSource(art); + const active2 = () => action === revision && !operation.closed && !isClosing(art) && sourceActive(); + const position = positionRestoration(art, value, active2); + const settle = () => { + if (!active2()) { + operation.dispose(); + return; + } + if (position.ready()) { + operation.dispose(); + update(); + } + }; + for (const name of ["video:seeked", "video:ended"]) { + art.on(name, settle); + operation.add(() => { + art.off(name, settle); + }); + } + try { + art.emit("setBar", "played", value / art.duration); + if (active2()) { + position.restore(() => { + art.seek = value; + }); + } + settle(); + } catch (error2) { + operation.dispose(); + throw error2; + } + }); + on("video:loadedmetadata", update); + on("video:durationchange", update); + on("video:emptied", update); + on("video:timeupdate", update); + on("video:seeking", update); + on("video:seeked", update); + on("video:ended", update); +} function mountProgressView(art, $control) { const { icons, option } = art; const { $player } = art.template; @@ -2016,6 +2532,7 @@ function progress(options) { mounted: ($control) => { mountProgressView(art, $control); installProgressInteractions(art, $control); + installProgressKeyboard(art, $control); } }); } @@ -2026,6 +2543,7 @@ function screenshot$1(option) { mounted: ($control) => { const { proxy } = controlEvents(art, $control); const { icons } = art; + keyboardButton(entryScope($control), $control); appendElement($control, icons.screenshot); proxy($control, "click", () => { silencePromise(art.screenshot()); @@ -2041,11 +2559,14 @@ function setting$1(option) { const { on, proxy } = controlEvents(art, $control); const { icons, i18n } = art; appendElement($control, icons.setting); + keyboardButton(entryScope($control), $control); + $control.setAttribute("aria-expanded", "false"); proxy($control, "click", () => { art.setting.toggle(); art.setting.resize(); }); on("setting", (value) => { + $control.setAttribute("aria-expanded", String(value)); tooltip($control, i18n.get(value ? "Hide Setting" : "Show Setting")); }); } @@ -2082,9 +2603,13 @@ function volume$1(option) { ...option, mounted: ($control) => { const { on, proxy } = controlEvents(art, $control); - const { icons } = art; + const { icons, i18n } = art; const $volume = appendElement($control, icons.volume); const $close = appendElement($control, icons.volumeClose); + for (const element of [$volume, $close]) { + keyboardButton(entryScope($control), element); + element.setAttribute("aria-label", i18n.get("Mute")); + } const $panel = appendElement($control, '
'); const $inner = appendElement($panel, '
'); const $value = appendElement($inner, `
`); @@ -2092,12 +2617,32 @@ function volume$1(option) { const $handle = appendElement($slider, `
`); const $loaded = appendElement($handle, `
`); const $indicator = appendElement($slider, `
`); + const scope = entryScope($control); + let revision = 0; + const updateSlider = keyboardSlider(scope, $slider, i18n.get("Volume"), () => ({ + min: 0, + max: 100, + value: art.muted ? 0 : art.volume * 100, + step: art.constructor.VOLUME_STEP * 100, + text: (value) => `${Math.round(value)}%` + }), (value) => { + const action = ++revision; + art.muted = false; + if (action === revision && !scope.closed && !isClosing(art)) + art.volume = value / 100; + }, "vertical"); function getVolumeFromEvent(event) { const { top, height } = getRect($slider); return 1 - (event.clientY - top) / height; } function update() { - if (art.muted || art.volume === 0) { + updateSlider(); + const focused = $control.ownerDocument.activeElement; + const muted = art.muted || art.volume === 0; + const visible = muted ? $close : $volume; + $volume.setAttribute("aria-pressed", String(art.muted)); + $close.setAttribute("aria-pressed", String(art.muted)); + if (muted) { setStyle($volume, "display", "none"); setStyle($close, "display", "flex"); setStyle($indicator, "top", "100%"); @@ -2111,6 +2656,8 @@ function volume$1(option) { setStyle($loaded, "top", `${100 - percentage}%`); $value.textContent = String(Math.floor(percentage)); } + if ((focused === $volume || focused === $close) && focused !== visible) + visible.focus({ preventScroll: true }); } update(); on("video:volumechange", update); @@ -2287,6 +2834,189 @@ function trackSelection(event, active2) { function captureSelection(event) { return event && selections.get(event) || (() => true); } +const interactive = "button,input,select,textarea,a[href],[tabindex],[contenteditable]"; +function selectorKeyboard(scope, owner, value, list, label) { + if (scope.closed) + return () => { + }; + const items = Array.from(list.children); + const complex = items.some((item) => item.querySelector(interactive)); + list.setAttribute("role", complex ? "group" : "listbox"); + list.setAttribute("aria-label", label); + let hovered = false; + let opened = false; + let dismissed = false; + let prefix = ""; + let typedAt = 0; + const expanded = () => items.length > 0 && (opened || hovered && !dismissed); + const trigger = () => value.querySelector('button,a[href],[role="button"]') || value; + const refresh = (restore = false) => { + if (scope.closed) + return; + const target = trigger(); + if (value.querySelector(interactive)) { + value.removeAttribute("role"); + value.removeAttribute("tabindex"); + } else { + value.setAttribute("role", "button"); + value.tabIndex = 0; + } + if (target !== value) { + value.removeAttribute("aria-haspopup"); + value.removeAttribute("aria-expanded"); + value.removeAttribute("aria-disabled"); + } + if (complex) + target.removeAttribute("aria-haspopup"); + else + target.setAttribute("aria-haspopup", "listbox"); + target.setAttribute("aria-expanded", String(expanded())); + target.setAttribute("aria-disabled", String(items.length === 0)); + if (restore && value.isConnected && value.ownerDocument.activeElement === value.ownerDocument.body) + target.focus({ preventScroll: true }); + }; + const visibility = (state2, hide = false) => { + opened = state2; + dismissed = hide; + owner.classList.toggle("art-selector-open", state2); + owner.classList.toggle("art-selector-dismissed", hide); + refresh(); + }; + const focus = (item) => { + if (!item || scope.closed) + return; + const target = item.querySelector(interactive) || item; + target.focus({ preventScroll: true }); + if (!scope.closed) + item.scrollIntoView({ block: "nearest", inline: "nearest" }); + }; + const open = (last = false) => { + if (scope.closed || !items.length) + return; + visibility(true); + prefix = ""; + focus(items.find((item) => item.classList.contains("art-current")) || items[last ? items.length - 1 : 0]); + }; + const close2 = () => { + if (scope.closed) + return; + const restore = list.contains(owner.ownerDocument.activeElement); + visibility(false, true); + prefix = ""; + if (restore && value.isConnected) + trigger().focus({ preventScroll: true }); + }; + keyboardButton(scope, value, () => { + value.click(); + if (owner.ownerDocument.activeElement === value) + open(); + }); + refresh(); + for (const item of items) { + const selected = item.classList.contains("art-current"); + if (!complex) { + item.setAttribute("role", "option"); + item.setAttribute("aria-selected", String(selected)); + } else { + item.setAttribute("aria-current", String(selected)); + } + if (!item.querySelector(interactive)) { + item.tabIndex = -1; + keyboardButton(scope, item, () => { + item.click(); + close2(); + }); + } + } + listen(scope, value, "keydown", (input) => { + const event = input; + if (!plainKey(event) || event.defaultPrevented || event.target !== value && event.target !== trigger()) + return; + if (event.key === "ArrowDown" || event.key === "ArrowUp") { + claimKey(event); + open(event.key === "ArrowUp"); + } else if (event.key === "Escape" && expanded()) { + claimKey(event); + close2(); + } + }); + listen(scope, value, "click", (event) => { + if (event.isTrusted && event.detail === 0 && trigger() !== value) + open(); + }); + listen(scope, list, "keydown", (input) => { + const event = input; + if (!plainKey(event) || event.defaultPrevented) + return; + if (event.key === "Escape") { + claimKey(event); + close2(); + return; + } + const index = items.indexOf(event.target); + if (index < 0) + return; + if (event.key.length !== 1) + prefix = ""; + let next; + switch (event.key) { + case "ArrowDown": + next = Math.min(index + 1, items.length - 1); + break; + case "ArrowUp": + next = Math.max(index - 1, 0); + break; + case "Home": + next = 0; + break; + case "End": + next = items.length - 1; + break; + case "ArrowLeft": + case "ArrowRight": + claimKey(event); + return; + default: { + if (event.key.length !== 1 || event.key === " ") + return; + const now = Date.now(); + prefix = now - typedAt < 500 ? prefix + event.key.toLocaleLowerCase() : event.key.toLocaleLowerCase(); + typedAt = now; + const query2 = [...prefix].every((char) => char === prefix[0]) ? prefix[0] : prefix; + for (let offset = 1; offset <= items.length; offset++) { + const candidate = (index + offset) % items.length; + if (items[candidate].textContent?.trim().toLocaleLowerCase().startsWith(query2)) { + next = candidate; + break; + } + } + } + } + claimKey(event); + if (next !== void 0) + focus(items[next]); + }); + listen(scope, list, "click", (event) => { + if (event.isTrusted && event.detail === 0) + close2(); + }); + listen(scope, owner, "mouseenter", () => { + hovered = true; + visibility(opened); + }); + listen(scope, owner, "mouseleave", () => { + hovered = false; + visibility(list.contains(owner.ownerDocument.activeElement)); + }); + listen(scope, owner, "focusout", (event) => { + if (!owner.contains(event.relatedTarget)) + visibility(false, true); + }); + scope.add(() => { + owner.classList.remove("art-selector-open", "art-selector-dismissed"); + }); + return refresh; +} const bindings$1 = /* @__PURE__ */ new WeakMap(); function bind(item, binding) { const previous = bindings$1.get(item); @@ -2304,13 +3034,17 @@ function setHTML(element, value) { function checkSelector(target) { if (!target) return; + const restore = target.$control_value.contains(target.$control_value.ownerDocument.activeElement); setHTML(target.$control_value, target.html); for (let index = 0; index < target.$control_option.length; index++) { const item = target.$control_option[index]; item.default = item === target; + const element = item.$control_item; + element.setAttribute(element.getAttribute("role") === "option" ? "aria-selected" : "aria-current", String(item.default)); if (item.default) inverseClass(item.$control_item, "art-current"); } + bindings$1.get(target)?.refresh?.(restore); } function renderSelector(art, check2, option, $ref, events) { const { proxy } = art.events; @@ -2352,8 +3086,11 @@ function renderSelector(art, check2, option, $ref, events) { return; if (option.onSelect) { const value = await option.onSelect.call(art, item, item.$control_item, event2); - if (active2()) + if (active2()) { + const restore = $value.contains($value.ownerDocument.activeElement); setHTML($value, value); + bindings$1.get(item)?.refresh?.(restore); + } } } catch (error2) { console.warn("ArtPlayer selector failed:", error2); @@ -2362,6 +3099,9 @@ function renderSelector(art, check2, option, $ref, events) { } }); events.push(event); + const refresh = selectorKeyboard(scope, $ref, $value, $list, String(option.tooltip || option.name || $value.textContent || art.i18n.get("Open"))); + for (const item of selector) + bindings$1.get(item).refresh = refresh; } class Control extends Component { constructor(art) { @@ -2371,8 +3111,21 @@ class Control extends Component { this.timer = Date.now(); const { constructor } = art; const { $player, $bottom } = this.art.template; - ownEntry(art, $bottom); - const { on } = controlEvents(art, $bottom); + const scope = ownEntry(art, $bottom); + const keyboardFocused = focusVisibility(scope, $player, () => { + this.show = true; + }); + const { on, proxy } = controlEvents(art, $bottom); + proxy($player, "focusin", (event) => { + art.isFocus = true; + art.isInput = event.target?.tagName === "INPUT"; + }); + proxy($player, "focusout", (event) => { + if (!$player.contains(event.relatedTarget)) { + art.isFocus = false; + art.isInput = false; + } + }); on("mousemove", () => { if (!isMobile) { this.show = true; @@ -2389,7 +3142,7 @@ class Control extends Component { this.isHover = includeFromEvent(event, $bottom); }); on("video:timeupdate", () => { - if (!art.setting.show && !this.isHover && !art.isInput && art.playing && this.show && Date.now() - this.timer >= constructor.CONTROL_HIDE_TIME) { + if (!art.setting.show && !this.isHover && !art.isInput && !keyboardFocused() && art.playing && this.show && Date.now() - this.timer >= constructor.CONTROL_HIDE_TIME) { this.show = false; } }); @@ -2966,7 +3719,7 @@ function editable(target) { return target.isContentEditable; } function acceptsHotkey(event, fallback) { - if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.isComposing || event.keyCode === 229) + if (isClaimedKey(event) || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.isComposing || event.keyCode === 229) return false; const doc = eventDocument(event, fallback); let active2 = asElement(doc.activeElement); @@ -2975,6 +3728,13 @@ function acceptsHotkey(event, fallback) { if (active2 && editable(active2)) return false; const first = asElement(event.composedPath?.()[0]) || asElement(event.target); + const enter = event.key === "Enter" || event.code === "Enter" || event.code === "NumpadEnter"; + const activation = enter || event.key === " " || event.code === "Space"; + if (activation) { + const selector = `button,summary,[role="button"],[role="switch"]${enter ? ",a[href]" : ""}`; + if (first?.closest?.(selector) || active2?.closest?.(selector)) + return false; + } return !first || !editable(first); } const states$4 = /* @__PURE__ */ new WeakMap(); @@ -3059,6 +3819,11 @@ function publishLanguage(name, value) { } } const zhCn = { + "Context Menu": "快捷菜单", + "Lock": "锁定", + "Back": "返回", + "Settings": "设置", + "Progress": "播放进度", "Video Info": "统计信息", "Close": "关闭", "Video Load Failed": "加载失败", @@ -3182,6 +3947,61 @@ class Icons { } } } +const origins = /* @__PURE__ */ new WeakMap(); +function infoKeyboard(art, scope, close2) { + const { $player, $info, $infoClose } = art.template; + if (!$info) + return; + const active2 = () => !scope.closed && !isClosing(art); + const visible = () => $player.classList.contains("art-info-show"); + const closeLabel = art.i18n.get("Close"); + if (!active2()) + return; + const groupLabel = art.i18n.get("Video Info"); + if (!active2()) + return; + $infoClose.setAttribute("aria-label", closeLabel); + $info.setAttribute("role", "group"); + $info.setAttribute("aria-label", groupLabel); + keyboardButton(scope, $infoClose, () => $infoClose.click(), visible); + listen(scope, $info, "keydown", (input) => { + const event = input; + if (active2() && visible() && plainKey(event) && !event.defaultPrevented && event.key === "Escape") { + claimKey(event); + close2(); + } + }); + const changed = (show) => { + if (!active2()) + return; + const doc = $player.ownerDocument; + const focused = doc.activeElement; + if (show) { + if (!$info.contains(focused)) { + origins.delete(art); + if (focused && $player.contains(focused)) { + origins.set(art, resolveFocusOrigin(focused)); + if ($player.classList.contains("art-keyboard-focus")) + $infoClose.focus({ preventScroll: true }); + } + } + } else { + const origin = origins.get(art); + origins.delete(art); + if (!$info.contains(focused)) + return; + const visibility = origin && doc.defaultView?.getComputedStyle(origin).visibility; + if (origin?.isConnected && $player.contains(origin) && origin.getClientRects().length && visibility !== "hidden" && visibility !== "collapse" && !origin.matches(":disabled") && !origin.closest("[inert]") && origin.getAttribute("aria-disabled") !== "true") + origin.focus({ preventScroll: true }); + else + focusPlayer(art); + } + }; + art.on("info", changed); + scope.add(() => { + art.off("info", changed); + }); +} function pollInfo(art, scope, close2) { const active2 = () => !scope.closed && !isClosing(art); const fail = (error2) => { @@ -3207,6 +4027,7 @@ function pollInfo(art, scope, close2) { scope.add(() => { art.off("destroy", destroy); }); + infoKeyboard(art, scope, close2); const loop = () => { try { for (const item of items) { @@ -3484,7 +4305,7 @@ function airplayMix(art) { proxy, template: { $video } } = art; - let available = true; + let available2 = true; const supported = window.WebKitPlaybackTargetAvailabilityEvent; if (isClosing(art)) return; @@ -3497,15 +4318,15 @@ function airplayMix(art) { return; switch (event.availability) { case "available": - available = true; + available2 = true; break; case "not-available": - available = false; + available2 = false; break; } }); } else { - available = false; + available2 = false; } if (isClosing(art)) return; @@ -3513,7 +4334,7 @@ function airplayMix(art) { value() { if (isClosing(art)) return; - if (available) { + if (available2) { const picker2 = $video.webkitShowPlaybackTargetPicker; if (isClosing(art)) return; @@ -3642,13 +4463,6 @@ function cssVarMix(art) { } }); } -const revisions = /* @__PURE__ */ new WeakMap(); -function positionRevision(art) { - return revisions.get(art) || 0; -} -function advancePosition(art) { - revisions.set(art, positionRevision(art) + 1); -} function currentTimeMix(art) { const { $video } = art.template; def(art, "currentTime", { @@ -4363,6 +5177,14 @@ function fullscreenMix(art) { art.off("video:loadedmetadata", metadata); }); } +function captureMovedFocus(root) { + const focused = root.ownerDocument?.activeElement; + const inside = focused && root.contains(focused); + return () => { + if (inside && focused.isConnected && root.contains(focused) && focused.ownerDocument.activeElement === focused.ownerDocument.body) + focused.focus({ preventScroll: true }); + }; +} function capturePlacement(node) { return { node, parent: node.parentNode, next: node.nextSibling }; } @@ -4415,6 +5237,7 @@ function webFullscreen(art) { return; const current2 = ++revision; const active2 = () => current2 === revision && !isClosing(art); + const restoreFocus = captureMovedFocus($player); if (value) { if (!saved) saved = { placement: capturePlacement($player), style: $player.getAttribute("style") }; @@ -4431,10 +5254,15 @@ function webFullscreen(art) { $player.style.height = "100%"; $player.classList.add("art-fullscreen-web"); } catch (error2) { - if (active2() && restore(snapshot, active2)) + if (active2() && restore(snapshot, active2)) { saved = void 0; + restoreFocus(); + } throw error2; } + if (!active2()) + return; + restoreFocus(); if (!active2()) return; art.emit("fullscreenWeb", true); @@ -4446,6 +5274,9 @@ function webFullscreen(art) { } else { $player.classList.remove("art-fullscreen-web"); } + if (!active2()) + return; + restoreFocus(); if (!active2()) return; art.emit("fullscreenWeb", false); @@ -4471,6 +5302,37 @@ function loadedMix(art) { get: () => $video.buffered.length ? $video.buffered.end($video.buffered.length - 1) : 0 }); } +function miniFocus(art) { + const player = art.template.$player; + let origin; + return { + entering() { + const doc = player.ownerDocument; + const focused = doc.activeElement; + const inside = focused && player.contains(focused); + if (!art.template.$mini?.contains(focused)) + origin = inside ? resolveFocusOrigin(focused) : void 0; + const keyboard = inside && player.classList.contains("art-keyboard-focus"); + return (focus) => { + if (keyboard && !isClosing(art) && (doc.activeElement === focused || doc.activeElement === doc.body)) + focus?.(); + }; + }, + leaving(popup) { + const doc = player.ownerDocument; + const inside = popup?.contains(doc.activeElement); + return () => { + if (!inside || isClosing(art) || doc.activeElement !== doc.body && !popup?.contains(doc.activeElement)) + return; + const visible = origin && doc.defaultView?.getComputedStyle(origin).visibility; + if (origin?.isConnected && origin.getClientRects().length && visible !== "hidden" && visible !== "collapse" && origin.getAttribute("aria-disabled") !== "true" && !origin.matches(":disabled") && !origin.closest("[inert]")) + origin.focus({ preventScroll: true }); + else + focusPlayer(art); + }; + } + }; +} function clampMini(left, top, geometry) { const maxLeft = Math.max(0, geometry.viewportWidth - geometry.width); const maxTop = Math.max(0, geometry.viewportHeight - geometry.height); @@ -4566,6 +5428,24 @@ function createMiniView(art, parent, active2, hide) { return; state2.append(play2, pause2); element.append(close2, state2); + keyboardButton(scope, close2, () => close2.click(), active2); + keyboardButton(scope, state2, () => (art.playing ? pause2 : play2).click(), active2); + const closeLabel = art.i18n.get("Close"); + if (scope.closed || isClosing(art)) + return; + close2.setAttribute("aria-label", closeLabel); + const groupLabel = art.i18n.get("Mini Player"); + if (scope.closed || isClosing(art)) + return; + element.setAttribute("role", "group"); + element.setAttribute("aria-label", groupLabel); + listen(scope, element, "keydown", (input) => { + const event = input; + if (active2() && plainKey(event) && !event.defaultPrevented && event.key === "Escape") { + claimKey(event); + hide(); + } + }); listen(scope, close2, "click", hide); listen(scope, play2, "click", () => { silencePromise(art.play()); @@ -4576,6 +5456,10 @@ function createMiniView(art, parent, active2, hide) { const update = () => { if (scope.closed) return; + const label = art.i18n.get(art.playing ? "Pause" : "Play"); + if (scope.closed || isClosing(art)) + return; + state2.setAttribute("aria-label", label); play2.style.display = art.playing ? "none" : "flex"; pause2.style.display = art.playing ? "flex" : "none"; }; @@ -4592,7 +5476,7 @@ function createMiniView(art, parent, active2, hide) { art.template.$mini = element; document2.body.append(element); if (!scope.closed) - return { element, cancelDrag, fresh: true }; + return { element, cancelDrag, fresh: true, focus: () => close2.focus({ preventScroll: true }) }; } catch (error2) { scope.dispose(); if (art.template.$mini === element) @@ -4609,6 +5493,7 @@ function mini(art) { let creating = false; let queued = false; const active2 = () => !isClosing(art) && $player.classList.contains("art-mini"); + const focus = miniFocus(art); function restore() { if (placement) { const saved = placement; @@ -4628,6 +5513,7 @@ function mini(art) { return; const current2 = ++revision; queued = false; + const restoreFocus = focus.leaving(art.template.$mini); restore(); if (isClosing(art) || current2 !== revision) return; @@ -4635,7 +5521,9 @@ function mini(art) { $player.classList.remove("art-mini"); if (art.template.$mini) { art.template.$mini.style.display = "none"; - art.emit("mini", false); + restoreFocus(); + if (!isClosing(art) && current2 === revision) + art.emit("mini", false); } } scope.add(() => { @@ -4655,6 +5543,7 @@ function mini(art) { queued = true; return; } + const enterFocus = focus.entering(); art.state = "mini"; if (isClosing(art) || current2 !== revision) return; @@ -4702,6 +5591,8 @@ function mini(art) { return; art.storage.set("left", position.left); } + if (!isClosing(art) && current2 === revision) + enterFocus(view.focus); if (!isClosing(art) && current2 === revision) art.emit("mini", true); } catch (error2) { @@ -5310,48 +6201,6 @@ function listenSource(scope, art, name, callback, once = true) { }); return guarded; } -const POSITION_TOLERANCE = 0.05; -function positionRestoration(art, target, active2) { - let expected; - let observedSeek = false; - let corrected = false; - let manual = false; - let revision = positionRevision(art); - const manualPosition = () => manual || positionRevision(art) !== revision; - const seeking = () => !!art.template?.$video?.seeking; - return { - restore() { - if (!active2() || manualPosition()) - return; - const previousRevision = positionRevision(art); - art.currentTime = target; - revision = positionRevision(art); - if (revision > previousRevision + 1) - manual = true; - if (!active2()) - return; - expected = art.currentTime; - if (!active2() || manualPosition()) - return; - observedSeek = seeking(); - }, - manual() { - manual = true; - }, - ready() { - if (!active2() || seeking()) - return false; - const missed = expected !== void 0 && Math.abs(art.currentTime - expected) > POSITION_TOLERANCE; - if (!manualPosition() && observedSeek && !corrected && expected !== void 0 && missed) { - corrected = true; - if (!active2()) - return false; - art.currentTime = expected; - } - return active2() && !seeking(); - } - }; -} function switchSource(art, url, currentTime) { return new Promise((resolve, reject) => { if (isClosing(art) || url === art.url) { @@ -6160,6 +7009,97 @@ function fastForward(art) { } }; } +function suspendFocus(scope, root) { + const original = /* @__PURE__ */ new Map(); + const inert = root.hasAttribute("inert"); + const hidden = root.getAttribute("aria-hidden"); + const restore = (element, value) => { + if (element.getAttribute("tabindex") !== "-1") + return; + if (value === null) + element.removeAttribute("tabindex"); + else + element.setAttribute("tabindex", value); + }; + scope.add(() => { + for (const [element, value] of original) + restore(element, value); + original.clear(); + if (!inert && root.getAttribute("inert") === "") + root.removeAttribute("inert"); + if (root.getAttribute("aria-hidden") === "true") { + if (hidden === null) + root.removeAttribute("aria-hidden"); + else + root.setAttribute("aria-hidden", hidden); + } + }); + if (scope.closed) + return; + if (!inert) + root.setAttribute("inert", ""); + root.setAttribute("aria-hidden", "true"); + const update = () => { + if (scope.closed) + return; + for (const [element, value] of original) { + if (!root.contains(element)) { + restore(element, value); + original.delete(element); + } + } + for (const element of root.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]")) { + if (!original.has(element)) { + original.set(element, element.getAttribute("tabindex")); + element.setAttribute("tabindex", "-1"); + } + } + }; + update(); + if (typeof MutationObserver !== "undefined") { + const observer = new MutationObserver(update); + observer.observe(root, { childList: true, subtree: true }); + scope.add(() => { + observer.disconnect(); + }); + } +} +function lockKeyboard(art, element, scope, locked) { + let suspension; + const active2 = () => !scope.closed && !isClosing(art); + const label = art.i18n.get("Lock"); + if (!active2()) + return () => { + }; + element.setAttribute("aria-label", label); + keyboardButton(scope, element); + listen(scope, element, "keydown", (input) => { + const event = input; + if (active2() && locked() && plainKey(event) && !event.defaultPrevented && event.key === "Escape") { + claimKey(event); + element.click(); + } + }); + const update = (state2) => { + if (!active2()) + return; + element.setAttribute("aria-pressed", String(state2)); + if (state2 && !suspension) { + const { $player, $bottom } = art.template; + const hiddenFocus = $bottom.contains($bottom.ownerDocument.activeElement) && $player.classList.contains("art-keyboard-focus"); + suspension = scope.child(); + suspendFocus(suspension, $bottom); + if (active2() && hiddenFocus) + element.focus({ preventScroll: true }); + } else if (!state2 && suspension) { + const previous = suspension; + suspension = void 0; + previous.dispose(); + } + }; + update(locked()); + return update; +} function lock(art) { const { layers, @@ -6201,13 +7141,24 @@ function lock(art) { const $unlock = appendElement($el, icons.unlock); if (scope.closed || isClosing(art)) return; - setStyle($lock, "display", "none"); + const updateKeyboard = lockKeyboard(art, $el, scope, getState); + if (scope.closed || isClosing(art)) + return; + if (getState()) { + setStyle($lock, "display", "inline-flex"); + if (!scope.closed && !isClosing(art)) + setStyle($unlock, "display", "none"); + } else { + setStyle($lock, "display", "none"); + } subscribeEntry(art, $el, "lock", (state2) => { if (isClosing(art)) return; setStyle($lock, "display", state2 ? "inline-flex" : "none"); if (!scope.closed && !isClosing(art)) setStyle($unlock, "display", state2 ? "none" : "inline-flex"); + if (!scope.closed && !isClosing(art)) + updateKeyboard(state2); }); }, click() { @@ -6787,6 +7738,170 @@ function flip(art) { } }; } +function available(element) { + const visibility = element.ownerDocument.defaultView?.getComputedStyle(element).visibility; + return element.isConnected && !element.matches(":disabled") && !element.closest("[inert]") && element.getAttribute("aria-disabled") !== "true" && element.getClientRects().length > 0 && visibility !== "hidden" && visibility !== "collapse"; +} +function settingFocusTargets(panel) { + return Array.from(panel.querySelectorAll('[tabindex="0"],button,input,select,textarea,a[href],[contenteditable]')).filter((element) => element.getAttribute("tabindex") !== "-1" && available(element)); +} +function returnSettingFocus(setting2) { + const { art, $parent } = setting2; + const player = art.template.$player; + const doc = $parent.ownerDocument; + const button = art.controls.setting; + if (isClosing(art) || !$parent.contains(doc.activeElement)) + return; + if (button && player.contains(button) && available(button)) + button.focus({ preventScroll: true }); + if (doc.activeElement === doc.body || $parent.contains(doc.activeElement)) + focusPlayer(art); +} +function focusSettingPanel(setting2, preferred, last = false) { + if (!setting2.show || isClosing(setting2.art) || !setting2.active) + return; + const panel = setting2.cache.get(setting2.active); + if (!panel || !settingScopeActive(settingPanelScope(panel))) + return; + const targets = settingFocusTargets(panel); + const selected = panel.querySelector(".art-setting-item.art-current"); + const target = targets.find((element) => preferred === element || preferred?.contains(element)) || (last ? targets[targets.length - 1] : targets.find((element) => selected?.contains(element)) || targets.find((element) => !element.classList.contains("art-setting-item-back")) || targets[0]); + target?.focus({ preventScroll: true }); + if (!isClosing(setting2.art)) + target?.scrollIntoView({ block: "nearest", inline: "nearest" }); +} +function captureSettingFocus(setting2) { + const doc = setting2.$parent.ownerDocument; + const focused = doc.activeElement; + const inside = setting2.$parent.contains(focused); + return (preferred) => { + if (!inside || isClosing(setting2.art)) + return; + if (doc.activeElement === doc.body || doc.activeElement === focused && !focused?.getClientRects().length) + focusSettingPanel(setting2, preferred); + }; +} +function installSettingKeyboard(setting2) { + const { art } = setting2; + const scope = getScope(art).child(); + if (scope.closed) + return; + const doc = () => setting2.$parent.ownerDocument; + let enterLast = false; + const close2 = () => { + setting2.show = false; + if (!scope.closed && !isClosing(art)) + setting2.render(); + }; + const changed = (show) => { + if (scope.closed || isClosing(art)) + return; + if (show) { + if (doc().activeElement === art.controls.setting && art.template.$player.classList.contains("art-keyboard-focus")) + focusSettingPanel(setting2, void 0, enterLast); + } else if (setting2.$parent.contains(doc().activeElement)) { + returnSettingFocus(setting2); + } + }; + art.on("setting", changed); + scope.add(() => { + art.off("setting", changed); + }); + listen(scope, art.template.$player, "keydown", (input) => { + const event = input; + if (!plainKey(event) || event.defaultPrevented || isClosing(art)) + return; + const target = event.target; + if (target === art.controls.setting) { + if (event.key === "ArrowDown" || event.key === "ArrowUp") { + claimKey(event); + if (!setting2.show) { + enterLast = event.key === "ArrowUp"; + try { + setting2.show = true; + } finally { + enterLast = false; + } + } else { + focusSettingPanel(setting2, void 0, event.key === "ArrowUp"); + } + } else if (event.key === "Escape" && setting2.show) { + claimKey(event); + close2(); + } + return; + } + if (!setting2.show || !setting2.$parent.contains(target)) + return; + if (event.key === "Escape") { + claimKey(event); + close2(); + return; + } + const row = target.closest(".art-setting-item"); + if (!row || target !== row && !target.matches('button,a[href],[role="button"]')) + return; + const panel = setting2.active && setting2.cache.get(setting2.active); + if (!panel) + return; + const currentItem = setting2.active?.find((item) => item.$item === row); + if (!settingScopeActive(settingPanelScope(panel)) || currentItem && !settingScopeActive(settingScope(currentItem))) { + if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) + claimKey(event); + return; + } + const targets = settingFocusTargets(panel); + const index = targets.indexOf(target); + if (index < 0) + return; + let next; + switch (event.key) { + case "ArrowDown": + next = Math.min(index + 1, targets.length - 1); + break; + case "ArrowUp": + next = Math.max(index - 1, 0); + break; + case "Home": + next = 0; + break; + case "End": + next = targets.length - 1; + break; + case "ArrowLeft": { + const back = panel.querySelector(".art-setting-item-back"); + claimKey(event); + back?.click(); + return; + } + case "ArrowRight": { + claimKey(event); + if (currentItem?.selector?.length) + target.click(); + return; + } + default: + return; + } + claimKey(event); + if (next !== void 0) + focusSettingPanel(setting2, targets[next]); + }); + let pending2 = false; + listen(scope, setting2.$parent, "focusout", (event) => { + const next = event.relatedTarget; + if (next && (setting2.$parent.contains(next) || next === art.controls.setting)) + return; + if (pending2) + return; + pending2 = true; + timeout(scope, () => { + pending2 = false; + if (!scope.closed && !isClosing(art) && setting2.show && !setting2.$parent.contains(doc().activeElement) && doc().activeElement !== art.controls.setting) + close2(); + }, 0); + }); +} function calculateSettingLayout(input) { const { containerWidth, containerHeight, requestedWidth, rows, rowHeight, controlCenter, bottom, padding } = input; const inset = Math.min(Math.max(0, padding), Math.max(0, containerWidth / 2)); @@ -6913,6 +8028,27 @@ function captureSettingItem(item) { } }; } +function nameSettingRange(item) { + const input = item.$item?.querySelector(".art-setting-range"); + if (input) + input.setAttribute("aria-label", item.$html?.textContent || ""); +} +function settingItemKeyboard(setting2, item, element, kind, scope) { + if (kind === "range") { + nameSettingRange(item); + return; + } + if (element.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")) + return; + if (kind === "switch") { + element.setAttribute("role", "switch"); + element.setAttribute("aria-checked", String(Boolean(item.switch))); + element.setAttribute("aria-disabled", String(!item.onSwitch)); + } else if (kind === "selector" && !item.selector?.length) { + element.setAttribute("aria-current", String(Boolean(item.default))); + } + keyboardButton(scope, element, () => element.click(), () => settingScopeActive(scope) && !isClosing(setting2.art)); +} const generations = /* @__PURE__ */ new WeakMap(); function checkSetting(setting2, target) { if (!target?.$parent) @@ -6920,6 +8056,8 @@ function checkSetting(setting2, target) { target.$parent.tooltip = target.html; setting2.traverse((item) => { item.default = item === target; + if (item.$item) + item.$item.setAttribute("aria-current", String(item.default)); if (item.default && item.$item) inverseClass(item.$item, "art-current"); }, target.$option); @@ -7107,6 +8245,7 @@ function updateSetting(setting2, target) { return item || target; if (!item) return setting2.add(target); + const restoreFocus = captureSettingFocus(setting2); cancelSettingAdd(item); cancelSettingUpdate(item); const restoreItem = captureSettingItem(item); @@ -7156,6 +8295,7 @@ function updateSetting(setting2, target) { } } ]); + restoreFocus(element); } catch (error2) { console.warn("ArtPlayer setting restore failed:", error2); } @@ -7191,6 +8331,7 @@ function updateSetting(setting2, target) { pending.delete(affected); } tree.dispose(); + restoreFocus(item.$item); return item; } catch (error2) { if (current2()) @@ -7209,6 +8350,8 @@ function bindContent(item, key, element) { set(value) { element.innerHTML = ""; append(element, value); + if (key === "html") + nameSettingRange(item); } }); } @@ -7231,6 +8374,10 @@ function createSettingHeader(setting2, item) { append($left, $icon); append($left, item.$parent.html); proxySetting(setting2.art, item.$parent, $item, "click", () => setting2.render(item.$parents), settingPanelScope($panel)); + const scope = settingPanelScope($panel); + if (!$item.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")) + keyboardButton(scope, $item, () => $item.click(), () => settingScopeActive(scope) && !isClosing(setting2.art)); + $item.setAttribute("aria-label", `${setting2.art.i18n.get("Back")}: ${$item.textContent?.trim() || ""}`); append($panel, $item); } function createSettingItem(setting2, item, isUpdate = false) { @@ -7341,6 +8488,7 @@ function createSettingItem(setting2, item, isUpdate = false) { get: () => $switchValue, set(value) { $switchValue = value; + $item.setAttribute("aria-checked", String(Boolean(value))); if (value) { setStyle($switchOff, "display", "none"); setStyle($switchOn, "display", null); @@ -7417,6 +8565,7 @@ function createSettingItem(setting2, item, isUpdate = false) { configurable: true, get: () => $item }); + settingItemKeyboard(setting2, item, $item, type, scope); if (isUpdate) { if (oldItem?.parentNode) oldItem.replaceWith($item); @@ -7450,6 +8599,7 @@ function createSettingItem(setting2, item, isUpdate = false) { function renderSetting(setting2, option = setting2.option) { if (isClosing(setting2.art)) return; + const restoreFocus = captureSettingFocus(setting2); const cached = setting2.cache.get(option); if (cached && !settingScopeActive(settingPanelScope(cached))) return; @@ -7485,6 +8635,8 @@ function renderSetting(setting2, option = setting2.option) { if (!current2()) return; addClass($panel, "art-setting-panel"); + $panel.setAttribute("role", "group"); + $panel.setAttribute("aria-label", option[0]?.$parent?.$html?.textContent || setting2.art.i18n.get("Settings")); append(setting2.$parent, $panel); inverseClass($panel, "art-current"); if (option[0]?.$parent) @@ -7521,6 +8673,8 @@ function renderSetting(setting2, option = setting2.option) { throw error2; } } + if (currentNavigation()) + restoreFocus(previous?.[0]?.$parent?.$item); } function subtitleOffset(art) { const { i18n, icons, constructor } = art; @@ -7567,6 +8721,7 @@ class Setting extends SettingBase { this.render(); installSettingEvents(this); } + installSettingKeyboard(this); } get builtin() { const result = []; @@ -7604,6 +8759,7 @@ class Setting extends SettingBase { releaseSettingTree(this, item); } remove(name) { + const restoreFocus = captureSettingFocus(this); const item = this.find(name); errorHandle(item, `Can't find [${name}] in the [setting]`); this.traverse((item2) => { @@ -7626,6 +8782,7 @@ class Setting extends SettingBase { } if (failures.length) throw new ResourceCleanupError(failures); + restoreFocus(); } update(target) { return updateSetting(this, target); @@ -7715,7 +8872,7 @@ class Storage { } } } -const css = ".art-video-player {\n --art-theme: #f00;\n --art-font-color: #fff;\n --art-background-color: #000;\n --art-text-shadow-color: rgba(0, 0, 0, 0.5);\n --art-transition-duration: 0.2s;\n --art-padding: 10px;\n --art-border-radius: 3px;\n --art-progress-height: 6px;\n --art-progress-color: rgba(255, 255, 255, 0.25);\n --art-progress-top-gap: 10px;\n --art-hover-color: rgba(255, 255, 255, 0.25);\n --art-loaded-color: rgba(255, 255, 255, 0.25);\n --art-state-size: 80px;\n --art-state-opacity: 0.8;\n --art-bottom-height: 100px;\n --art-bottom-offset: 20px;\n --art-bottom-gap: 5px;\n --art-highlight-width: 8px;\n --art-highlight-color: rgba(255, 255, 255, 0.5);\n --art-control-height: 46px;\n --art-control-opacity: 0.75;\n --art-control-icon-size: 36px;\n --art-control-icon-scale: 1.1;\n --art-volume-height: 120px;\n --art-volume-handle-size: 14px;\n --art-lock-size: 36px;\n --art-indicator-scale: 0;\n --art-indicator-size: 16px;\n --art-fullscreen-web-index: 9999;\n --art-settings-icon-size: 24px;\n --art-settings-max-height: 300px;\n --art-selector-max-height: 300px;\n --art-contextmenus-min-width: 250px;\n --art-subtitle-font-size: 20px;\n --art-subtitle-gap: 5px;\n --art-subtitle-bottom: 15px;\n --art-subtitle-border: #000;\n --art-widget-background: rgba(0, 0, 0, 0.85);\n --art-tip-background: rgba(0, 0, 0, 0.7);\n --art-scrollbar-size: 4px;\n --art-scrollbar-background: rgba(255, 255, 255, 0.25);\n --art-scrollbar-background-hover: rgba(255, 255, 255, 0.5);\n --art-mini-progress-height: 2px;\n}\n.art-bg-cover {\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.art-bottom-gradient {\n background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0.4), transparent);\n background-repeat: repeat-x;\n background-position: center bottom;\n}\n.art-backdrop-filter {\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n backdrop-filter: saturate(180%) blur(20px);\n background-color: rgba(0, 0, 0, 0.75) !important;\n}\n.art-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.art-video-player {\n position: relative;\n margin: 0 auto;\n width: 100%;\n height: 100%;\n outline: 0;\n zoom: 1;\n padding: 0;\n text-align: left;\n direction: ltr;\n font-size: 14px;\n line-height: 1.3;\n user-select: none;\n box-sizing: border-box;\n color: var(--art-font-color);\n background-color: var(--art-background-color);\n text-shadow: 0 0 2px var(--art-text-shadow-color);\n font-family: PingFang SC, Helvetica Neue, Microsoft YaHei, Roboto, Arial, sans-serif;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n -ms-high-contrast-adjust: none;\n}\n.art-video-player *,\n.art-video-player *::before,\n.art-video-player *::after {\n box-sizing: border-box;\n}\n.art-video-player ::-webkit-scrollbar {\n width: var(--art-scrollbar-size);\n height: var(--art-scrollbar-size);\n}\n.art-video-player ::-webkit-scrollbar-thumb {\n background-color: var(--art-scrollbar-background);\n}\n.art-video-player ::-webkit-scrollbar-thumb:hover {\n background-color: var(--art-scrollbar-background-hover);\n}\n.art-video-player img {\n max-width: 100%;\n vertical-align: top;\n}\n.art-video-player svg {\n fill: var(--art-font-color);\n}\n.art-video-player a {\n color: var(--art-font-color);\n text-decoration: none;\n}\n.art-icon {\n line-height: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.art-video-player.art-backdrop .art-contextmenus,\n.art-video-player.art-backdrop .art-info,\n.art-video-player.art-backdrop .art-settings,\n.art-video-player.art-backdrop .art-layer-auto-playback,\n.art-video-player.art-backdrop .art-selector-list,\n.art-video-player.art-backdrop .art-volume-inner {\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n backdrop-filter: saturate(180%) blur(20px);\n background-color: rgba(0, 0, 0, 0.75) !important;\n}\n.art-video {\n position: absolute;\n inset: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n}\n.art-poster {\n position: absolute;\n inset: 0;\n z-index: 11;\n width: 100%;\n height: 100%;\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n pointer-events: none;\n}\n.art-video-player .art-subtitle {\n display: none;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n position: absolute;\n z-index: 20;\n width: 100%;\n padding: 0 5%;\n text-align: center;\n pointer-events: none;\n gap: var(--art-subtitle-gap);\n bottom: var(--art-subtitle-bottom);\n font-size: var(--art-subtitle-font-size);\n transition: bottom var(--art-transition-duration) ease;\n text-shadow: var(--art-subtitle-border) 1px 0 1px, var(--art-subtitle-border) 0 1px 1px, var(--art-subtitle-border) -1px 0 1px, var(--art-subtitle-border) 0 -1px 1px, var(--art-subtitle-border) 1px 1px 1px, var(--art-subtitle-border) -1px -1px 1px, var(--art-subtitle-border) 1px -1px 1px, var(--art-subtitle-border) -1px 1px 1px;\n}\n.art-video-player.art-subtitle-show .art-subtitle {\n display: flex;\n}\n.art-video-player.art-control-show .art-subtitle {\n bottom: calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom));\n}\n.art-danmuku {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: hidden;\n}\n.art-video-player .art-layers {\n position: absolute;\n inset: 0;\n z-index: 40;\n width: 100%;\n height: 100%;\n display: none;\n pointer-events: none;\n}\n.art-video-player .art-layers .art-layer {\n pointer-events: auto;\n}\n.art-video-player.art-layer-show .art-layers {\n display: flex;\n}\n.art-video-player .art-mask {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n inset: 0;\n z-index: 50;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-video-player .art-mask .art-state {\n display: flex;\n justify-content: center;\n align-items: center;\n opacity: 0;\n transform: scale(2);\n width: var(--art-state-size);\n height: var(--art-state-size);\n transition: all var(--art-transition-duration) ease;\n}\n.art-video-player.art-mask-show .art-state {\n pointer-events: auto;\n opacity: var(--art-state-opacity);\n transform: scale(1);\n}\n.art-video-player.art-loading-show .art-state {\n display: none;\n}\n.art-video-player .art-loading {\n display: none;\n justify-content: center;\n align-items: center;\n position: absolute;\n inset: 0;\n z-index: 70;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-video-player.art-loading-show .art-loading {\n display: flex;\n}\n.art-video-player.art-loading-show .art-mask {\n display: none;\n}\n.art-video-player .art-bottom {\n position: absolute;\n inset: 0;\n z-index: 60;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n padding: 0 var(--art-padding);\n transition: all var(--art-transition-duration) ease;\n background-size: 100% var(--art-bottom-height);\n background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0.4), transparent);\n background-repeat: repeat-x;\n background-position: center bottom;\n}\n.art-video-player .art-bottom .art-controls,\n.art-video-player .art-bottom .art-progress {\n transform: translateY(var(--art-bottom-offset));\n transition: transform var(--art-transition-duration) ease;\n}\n.art-video-player.art-control-show .art-bottom,\n.art-video-player.art-hover .art-bottom {\n opacity: 1;\n}\n.art-video-player.art-control-show .art-bottom .art-controls,\n.art-video-player.art-hover .art-bottom .art-controls,\n.art-video-player.art-control-show .art-bottom .art-progress,\n.art-video-player.art-hover .art-bottom .art-progress {\n transform: translateY(0);\n}\n.art-bottom .art-progress {\n position: relative;\n z-index: 0;\n cursor: pointer;\n pointer-events: auto;\n padding-top: var(--art-progress-top-gap);\n padding-bottom: var(--art-bottom-gap);\n}\n.art-bottom .art-progress .art-control-progress {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n height: var(--art-progress-height);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner {\n display: flex;\n align-items: center;\n position: relative;\n height: 50%;\n width: 100%;\n transition: height var(--art-transition-duration) ease;\n background-color: var(--art-progress-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-hover-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded {\n position: absolute;\n inset: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-loaded-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played {\n position: absolute;\n inset: 0;\n z-index: 20;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-theme);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n right: auto;\n pointer-events: auto;\n width: var(--art-highlight-width) !important;\n transform: translateX(calc(var(--art-highlight-width) / -2));\n background-color: var(--art-highlight-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n z-index: 40;\n left: 0;\n border-radius: 50%;\n width: var(--art-indicator-size);\n height: var(--art-indicator-size);\n transform: scale(var(--art-indicator-scale));\n margin-left: calc(var(--art-indicator-size) / -2);\n transition: transform var(--art-transition-duration) ease;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon {\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover {\n transform: scale(1.2) !important;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active {\n transform: scale(1) !important;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip {\n transform-origin: bottom center;\n transform: scale(0.5);\n opacity: 0;\n position: absolute;\n z-index: 50;\n top: -25px;\n left: 0;\n padding: 3px 5px;\n line-height: 1;\n font-size: 12px;\n border-radius: var(--art-border-radius);\n white-space: nowrap;\n background-color: var(--art-tip-background);\n transition: transform var(--art-transition-duration) ease, opacity var(--art-transition-duration) ease;\n}\n.art-bottom .art-progress .art-control-thumbnails {\n transform-origin: bottom center;\n transform: scale(0.5);\n opacity: 0;\n position: absolute;\n bottom: calc(var(--art-bottom-gap) + 10px);\n left: 0;\n border-radius: var(--art-border-radius);\n pointer-events: none;\n background-color: var(--art-widget-background);\n transition: transform var(--art-transition-duration) ease, opacity var(--art-transition-duration) ease;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 2px -1px rgba(0, 0, 0, 0.2);\n}\n.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner {\n height: 100%;\n}\n.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator {\n transform: scale(1);\n}\n.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,\n.art-progress-hover .art-bottom .art-progress .art-control-thumbnails {\n transform: scale(1);\n opacity: 1;\n}\n.art-video-player .art-controls {\n position: relative;\n z-index: 10;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n flex-shrink: 0;\n height: auto;\n min-height: var(--art-control-height);\n}\n.art-video-player .art-controls .art-controls-left,\n.art-video-player .art-controls .art-controls-right {\n display: flex;\n flex-wrap: wrap;\n max-width: 100%;\n min-height: var(--art-control-height);\n}\n.art-video-player .art-controls .art-controls-center {\n display: none;\n justify-content: center;\n align-items: center;\n flex: 1;\n height: 100%;\n padding: 0 10px;\n}\n.art-video-player .art-controls .art-controls-right {\n justify-content: flex-end;\n margin-left: auto;\n}\n.art-video-player .art-controls .art-control {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n max-width: 100%;\n cursor: pointer;\n white-space: nowrap;\n opacity: var(--art-control-opacity);\n min-height: var(--art-control-height);\n min-width: var(--art-control-height);\n transition: opacity var(--art-transition-duration) ease;\n}\n.art-video-player .art-controls .art-control .art-icon {\n height: var(--art-control-icon-size);\n width: var(--art-control-icon-size);\n transform: scale(var(--art-control-icon-scale));\n transition: transform var(--art-transition-duration) ease;\n}\n.art-video-player .art-controls .art-control .art-icon:active {\n transform: scale(calc(var(--art-control-icon-scale) * 0.8));\n}\n.art-video-player .art-controls .art-control:hover {\n opacity: 1;\n}\n.art-control-volume {\n position: relative;\n}\n.art-control-volume .art-volume-panel {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n left: 0;\n right: 0;\n padding: 0 5px;\n font-size: 12px;\n text-align: center;\n cursor: default;\n opacity: 0;\n transform: translateY(10px);\n pointer-events: none;\n bottom: var(--art-control-height);\n width: var(--art-control-height);\n height: var(--art-volume-height);\n transition: all var(--art-transition-duration) ease;\n}\n.art-control-volume .art-volume-panel .art-volume-inner {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 10px;\n height: 100%;\n width: 100%;\n padding: 10px 0 12px;\n border-radius: var(--art-border-radius);\n background-color: var(--art-widget-background);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider {\n flex: 1;\n width: 100%;\n display: flex;\n cursor: pointer;\n position: relative;\n justify-content: center;\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle {\n position: relative;\n display: flex;\n justify-content: center;\n width: 2px;\n border-radius: var(--art-border-radius);\n overflow: hidden;\n background-color: rgba(255, 255, 255, 0.25);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n background-color: var(--art-theme);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator {\n position: absolute;\n width: var(--art-volume-handle-size);\n height: var(--art-volume-handle-size);\n margin-top: calc(var(--art-volume-handle-size) / -2);\n flex-shrink: 0;\n transform: scale(1);\n border-radius: 100%;\n background-color: var(--art-theme);\n transition: transform var(--art-transition-duration) ease;\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator {\n transform: scale(0.9);\n}\n.art-control-volume:hover .art-volume-panel {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n.art-video-player .art-notice {\n display: none;\n position: absolute;\n inset: 0;\n z-index: 80;\n width: 100%;\n height: 100%;\n height: auto;\n bottom: auto;\n padding: var(--art-padding);\n pointer-events: none;\n}\n.art-video-player .art-notice .art-notice-inner {\n display: inline-flex;\n padding: 5px;\n line-height: 1;\n border-radius: var(--art-border-radius);\n background-color: var(--art-tip-background);\n}\n.art-video-player.art-notice-show .art-notice {\n display: flex;\n}\n.art-video-player .art-contextmenus {\n display: none;\n flex-direction: column;\n position: absolute;\n z-index: 120;\n padding: 5px 0;\n border-radius: var(--art-border-radius);\n font-size: 12px;\n background-color: var(--art-widget-background);\n min-width: var(--art-contextmenus-min-width);\n}\n.art-video-player .art-contextmenus .art-contextmenu {\n cursor: pointer;\n display: flex;\n padding: 10px 15px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-contextmenus .art-contextmenu span {\n padding: 0 8px;\n}\n.art-video-player .art-contextmenus .art-contextmenu span:hover,\n.art-video-player .art-contextmenus .art-contextmenu span.art-current {\n color: var(--art-theme);\n}\n.art-video-player .art-contextmenus .art-contextmenu:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-contextmenus .art-contextmenu:last-child {\n border-bottom: none;\n}\n.art-video-player.art-contextmenu-show .art-contextmenus {\n display: flex;\n}\n.art-video-player .art-settings {\n display: none;\n flex-direction: column;\n position: absolute;\n z-index: 90;\n left: auto;\n overflow-y: auto;\n overflow-x: hidden;\n border-radius: var(--art-border-radius);\n max-height: var(--art-settings-max-height);\n right: var(--art-padding);\n bottom: var(--art-controls-height, var(--art-control-height));\n transition: all var(--art-transition-duration) ease;\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-settings .art-setting-panel {\n display: none;\n flex-direction: column;\n}\n.art-video-player .art-settings .art-setting-panel.art-current {\n display: flex;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 5px;\n padding: 0 5px;\n cursor: pointer;\n overflow: hidden;\n transition: background-color var(--art-transition-duration) ease;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current {\n color: var(--art-theme);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check {\n visibility: hidden;\n height: 15px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check {\n visibility: visible;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n gap: 5px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n height: var(--art-settings-icon-size);\n width: var(--art-settings-icon-size);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-width: 0;\n max-width: 55%;\n gap: 5px;\n font-size: 12px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(255, 255, 255, 0.5);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-width: 32px;\n height: 24px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range {\n height: 3px;\n width: 80px;\n outline: none;\n appearance: none;\n background-color: rgba(255, 255, 255, 0.2);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item-back {\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.art-video-player.art-setting-show .art-settings {\n display: flex;\n}\n.art-video-player .art-info {\n display: none;\n position: absolute;\n left: var(--art-padding);\n top: var(--art-padding);\n z-index: 100;\n padding: 10px;\n font-size: 12px;\n border-radius: var(--art-border-radius);\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-info .art-info-panel {\n display: flex;\n flex-direction: column;\n gap: 5px;\n}\n.art-video-player .art-info .art-info-panel .art-info-item {\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.art-video-player .art-info .art-info-panel .art-info-item .art-info-title {\n width: 100px;\n text-align: right;\n}\n.art-video-player .art-info .art-info-panel .art-info-item .art-info-content {\n width: 250px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n user-select: all;\n}\n.art-video-player .art-info .art-info-close {\n position: absolute;\n top: 5px;\n right: 5px;\n cursor: pointer;\n}\n.art-video-player.art-info-show .art-info {\n display: flex;\n}\n.art-hide-cursor * {\n cursor: none !important;\n}\n.art-video-player[data-aspect-ratio] {\n overflow: hidden;\n}\n.art-video-player[data-aspect-ratio] .art-video {\n object-fit: fill;\n box-sizing: content-box;\n}\n.art-fullscreen {\n --art-progress-height: 8px;\n --art-indicator-size: 20px;\n --art-control-height: 60px;\n --art-control-icon-scale: 1.3;\n}\n.art-fullscreen-web {\n --art-progress-height: 8px;\n --art-indicator-size: 20px;\n --art-control-height: 60px;\n --art-control-icon-scale: 1.3;\n position: fixed;\n inset: 0;\n z-index: var(--art-fullscreen-web-index);\n width: 100%;\n height: 100%;\n}\n.art-mini-popup {\n position: fixed;\n z-index: 9999;\n width: 320px;\n height: 180px;\n max-width: 100vw;\n max-height: 100vh;\n background: #000;\n border-radius: var(--art-border-radius);\n cursor: move;\n user-select: none;\n overflow: hidden;\n transition: opacity 0.2s ease;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);\n}\n.art-mini-popup svg {\n fill: #fff;\n}\n.art-mini-popup .art-video {\n pointer-events: none;\n}\n.art-mini-popup .art-mini-close {\n position: absolute;\n z-index: 20;\n right: 10px;\n top: 10px;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n.art-mini-popup .art-mini-state {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.2s ease;\n background-color: rgba(0, 0, 0, 0.25);\n}\n.art-mini-popup .art-mini-state .art-icon {\n opacity: 0.75;\n cursor: pointer;\n transform: scale(3);\n pointer-events: auto;\n transition: transform 0.2s ease;\n}\n.art-mini-popup .art-mini-state .art-icon:active {\n transform: scale(2.5);\n}\n.art-mini-popup.art-mini-dragging {\n opacity: 0.9;\n}\n.art-mini-popup:hover .art-mini-close,\n.art-mini-popup:hover .art-mini-state {\n opacity: 1;\n}\n.art-video-player[data-flip='horizontal'] .art-video {\n transform: scaleX(-1);\n}\n.art-video-player[data-flip='vertical'] .art-video {\n transform: scaleY(-1);\n}\n.art-video-player .art-layer-lock {\n display: none;\n justify-content: center;\n align-items: center;\n position: absolute;\n top: 50%;\n border-radius: 50%;\n transform: translateY(-50%);\n height: var(--art-lock-size);\n width: var(--art-lock-size);\n left: var(--art-padding);\n background-color: var(--art-tip-background);\n}\n.art-video-player .art-layer-auto-playback {\n display: none;\n gap: 10px;\n align-items: center;\n position: absolute;\n border-radius: var(--art-border-radius);\n padding: 10px;\n line-height: 1;\n left: var(--art-padding);\n bottom: calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-close {\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-close svg {\n width: 15px;\n height: 15px;\n fill: var(--art-theme);\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-jump {\n color: var(--art-theme);\n cursor: pointer;\n}\n.art-video-player.art-lock .art-subtitle {\n bottom: var(--art-subtitle-bottom) !important;\n}\n.art-video-player.art-mini-progress-bar .art-bottom,\n.art-video-player.art-lock .art-bottom {\n opacity: 1;\n padding: 0;\n background-image: none;\n}\n.art-video-player.art-mini-progress-bar .art-bottom .art-controls,\n.art-video-player.art-lock .art-bottom .art-controls,\n.art-video-player.art-mini-progress-bar .art-bottom .art-progress,\n.art-video-player.art-lock .art-bottom .art-progress {\n transform: translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4));\n}\n.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,\n.art-video-player.art-lock .art-bottom .art-progress-indicator {\n display: none !important;\n}\n.art-video-player.art-control-show .art-layer-lock {\n display: flex;\n}\n.art-control-selector {\n position: relative;\n display: flex;\n justify-content: center;\n}\n.art-control-selector .art-selector-list {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n position: absolute;\n border-radius: var(--art-border-radius);\n overflow-y: auto;\n overflow-x: hidden;\n opacity: 0;\n transform: translateY(10px);\n pointer-events: none;\n bottom: var(--art-control-height);\n max-height: var(--art-selector-max-height);\n background-color: var(--art-widget-background);\n transition: all var(--art-transition-duration) ease;\n}\n.art-control-selector .art-selector-list .art-selector-item {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n padding: 10px 15px;\n flex-shrink: 0;\n line-height: 1;\n}\n.art-control-selector .art-selector-list .art-selector-item:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-control-selector .art-selector-list .art-selector-item:hover,\n.art-control-selector .art-selector-list .art-selector-item.art-current {\n color: var(--art-theme);\n}\n.art-control-selector:hover .art-selector-list {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n.art-video-player {\n /*! Hint.css - v2.7.0 - 2021-10-01\n * https://kushagra.dev/lab/hint/\n * Copyright (c) 2021 Kushagra Gour */\n /*-------------------------------------*\\\n HINT.css - A CSS tooltip library\n \\*-------------------------------------*/\n /**\n * HINT.css is a tooltip library made in pure CSS.\n *\n * Source: https://github.com/chinchang/hint.css\n * Demo: http://kushagragour.in/lab/hint/\n *\n */\n /**\n * source: hint-core.scss\n *\n * Defines the basic styling for the tooltip.\n * Each tooltip is made of 2 parts:\n * 1) body (:after)\n * 2) arrow (:before)\n *\n * Classes added:\n * 1) hint\n */\n /**\n * source: hint-position.scss\n *\n * Defines the positoning logic for the tooltips.\n *\n * Classes added:\n * 1) hint--top\n * 2) hint--bottom\n * 3) hint--left\n * 4) hint--right\n */\n /**\n * set default color for tooltip arrows\n */\n /**\n * top tooltip\n */\n /**\n * bottom tooltip\n */\n /**\n * right tooltip\n */\n /**\n * left tooltip\n */\n /**\n * top-left tooltip\n */\n /**\n * top-right tooltip\n */\n /**\n * bottom-left tooltip\n */\n /**\n * bottom-right tooltip\n */\n /**\n * source: hint-sizes.scss\n *\n * Defines width restricted tooltips that can span\n * across multiple lines.\n *\n * Classes added:\n * 1) hint--small\n * 2) hint--medium\n * 3) hint--large\n *\n */\n /**\n * source: hint-theme.scss\n *\n * Defines basic theme for tooltips.\n *\n */\n /**\n * source: hint-color-types.scss\n *\n * Contains tooltips of various types based on color differences.\n *\n * Classes added:\n * 1) hint--error\n * 2) hint--warning\n * 3) hint--info\n * 4) hint--success\n *\n */\n /**\n * Error\n */\n /**\n * Warning\n */\n /**\n * Info\n */\n /**\n * Success\n */\n /**\n * source: hint-always.scss\n *\n * Defines a persisted tooltip which shows always.\n *\n * Classes added:\n * 1) hint--always\n *\n */\n /**\n * source: hint-rounded.scss\n *\n * Defines rounded corner tooltips.\n *\n * Classes added:\n * 1) hint--rounded\n *\n */\n /**\n * source: hint-effects.scss\n *\n * Defines various transition effects for the tooltips.\n *\n * Classes added:\n * 1) hint--no-animate\n * 2) hint--bounce\n *\n */\n}\n.art-video-player [class*='hint--'] {\n position: relative;\n display: inline-block;\n font-style: normal;\n /**\n * tooltip arrow\n */\n /**\n * tooltip body\n */\n}\n.art-video-player [class*='hint--']:before,\n.art-video-player [class*='hint--']:after {\n position: absolute;\n -webkit-transform: translate3d(0, 0, 0);\n -moz-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n visibility: hidden;\n opacity: 0;\n z-index: 1000000;\n pointer-events: none;\n -webkit-transition: 0.3s ease;\n -moz-transition: 0.3s ease;\n transition: 0.3s ease;\n -webkit-transition-delay: 0ms;\n -moz-transition-delay: 0ms;\n transition-delay: 0ms;\n}\n.art-video-player [class*='hint--']:hover:before,\n.art-video-player [class*='hint--']:hover:after {\n visibility: visible;\n opacity: 1;\n}\n.art-video-player [class*='hint--']:hover:before,\n.art-video-player [class*='hint--']:hover:after {\n -webkit-transition-delay: 100ms;\n -moz-transition-delay: 100ms;\n transition-delay: 100ms;\n}\n.art-video-player [class*='hint--']:before {\n content: '';\n position: absolute;\n background: transparent;\n border: 6px solid transparent;\n z-index: 1000001;\n}\n.art-video-player [class*='hint--']:after {\n background: #000000;\n color: white;\n padding: 8px 10px;\n font-size: 12px;\n font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n line-height: 12px;\n white-space: nowrap;\n}\n.art-video-player [class*='hint--'][aria-label]:after {\n content: attr(aria-label);\n}\n.art-video-player [class*='hint--'][data-hint]:after {\n content: attr(data-hint);\n}\n.art-video-player [aria-label='']:before,\n.art-video-player [aria-label='']:after,\n.art-video-player [data-hint='']:before,\n.art-video-player [data-hint='']:after {\n display: none !important;\n}\n.art-video-player .hint--top-left:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--top-right:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--top:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--bottom-left:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--bottom-right:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--bottom:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--left:before {\n border-left-color: #000000;\n}\n.art-video-player .hint--right:before {\n border-right-color: #000000;\n}\n.art-video-player .hint--top:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top:before,\n.art-video-player .hint--top:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top:after {\n -webkit-transform: translateX(-50%);\n -moz-transform: translateX(-50%);\n transform: translateX(-50%);\n}\n.art-video-player .hint--top:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top:hover:after {\n -webkit-transform: translateX(-50%) translateY(-8px);\n -moz-transform: translateX(-50%) translateY(-8px);\n transform: translateX(-50%) translateY(-8px);\n}\n.art-video-player .hint--bottom:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom:before,\n.art-video-player .hint--bottom:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom:after {\n -webkit-transform: translateX(-50%);\n -moz-transform: translateX(-50%);\n transform: translateX(-50%);\n}\n.art-video-player .hint--bottom:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom:hover:after {\n -webkit-transform: translateX(-50%) translateY(8px);\n -moz-transform: translateX(-50%) translateY(8px);\n transform: translateX(-50%) translateY(8px);\n}\n.art-video-player .hint--right:before {\n margin-left: -11px;\n margin-bottom: -6px;\n}\n.art-video-player .hint--right:after {\n margin-bottom: -14px;\n}\n.art-video-player .hint--right:before,\n.art-video-player .hint--right:after {\n left: 100%;\n bottom: 50%;\n}\n.art-video-player .hint--right:hover:before {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--right:hover:after {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--left:before {\n margin-right: -11px;\n margin-bottom: -6px;\n}\n.art-video-player .hint--left:after {\n margin-bottom: -14px;\n}\n.art-video-player .hint--left:before,\n.art-video-player .hint--left:after {\n right: 100%;\n bottom: 50%;\n}\n.art-video-player .hint--left:hover:before {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--left:hover:after {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--top-left:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top-left:before,\n.art-video-player .hint--top-left:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top-left:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top-left:after {\n -webkit-transform: translateX(-100%);\n -moz-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n.art-video-player .hint--top-left:after {\n margin-left: 12px;\n}\n.art-video-player .hint--top-left:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top-left:hover:after {\n -webkit-transform: translateX(-100%) translateY(-8px);\n -moz-transform: translateX(-100%) translateY(-8px);\n transform: translateX(-100%) translateY(-8px);\n}\n.art-video-player .hint--top-right:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top-right:before,\n.art-video-player .hint--top-right:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top-right:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top-right:after {\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n transform: translateX(0);\n}\n.art-video-player .hint--top-right:after {\n margin-left: -12px;\n}\n.art-video-player .hint--top-right:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top-right:hover:after {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--bottom-left:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom-left:before,\n.art-video-player .hint--bottom-left:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom-left:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom-left:after {\n -webkit-transform: translateX(-100%);\n -moz-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n.art-video-player .hint--bottom-left:after {\n margin-left: 12px;\n}\n.art-video-player .hint--bottom-left:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom-left:hover:after {\n -webkit-transform: translateX(-100%) translateY(8px);\n -moz-transform: translateX(-100%) translateY(8px);\n transform: translateX(-100%) translateY(8px);\n}\n.art-video-player .hint--bottom-right:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom-right:before,\n.art-video-player .hint--bottom-right:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom-right:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom-right:after {\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n transform: translateX(0);\n}\n.art-video-player .hint--bottom-right:after {\n margin-left: -12px;\n}\n.art-video-player .hint--bottom-right:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom-right:hover:after {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--small:after,\n.art-video-player .hint--medium:after,\n.art-video-player .hint--large:after {\n white-space: normal;\n line-height: 1.4em;\n word-wrap: break-word;\n}\n.art-video-player .hint--small:after {\n width: 80px;\n}\n.art-video-player .hint--medium:after {\n width: 150px;\n}\n.art-video-player .hint--large:after {\n width: 300px;\n}\n.art-video-player [class*='hint--'] {\n /**\n * tooltip body\n */\n}\n.art-video-player [class*='hint--']:after {\n text-shadow: 0 -1px 0px black;\n box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);\n}\n.art-video-player .hint--error:after {\n background-color: #b34e4d;\n text-shadow: 0 -1px 0px #592726;\n}\n.art-video-player .hint--error.hint--top-left:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--top-right:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--top:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom-left:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom-right:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--left:before {\n border-left-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--right:before {\n border-right-color: #b34e4d;\n}\n.art-video-player .hint--warning:after {\n background-color: #c09854;\n text-shadow: 0 -1px 0px #6c5328;\n}\n.art-video-player .hint--warning.hint--top-left:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--top-right:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--top:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom-left:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom-right:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--left:before {\n border-left-color: #c09854;\n}\n.art-video-player .hint--warning.hint--right:before {\n border-right-color: #c09854;\n}\n.art-video-player .hint--info:after {\n background-color: #3986ac;\n text-shadow: 0 -1px 0px #1a3c4d;\n}\n.art-video-player .hint--info.hint--top-left:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--top-right:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--top:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom-left:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom-right:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--left:before {\n border-left-color: #3986ac;\n}\n.art-video-player .hint--info.hint--right:before {\n border-right-color: #3986ac;\n}\n.art-video-player .hint--success:after {\n background-color: #458746;\n text-shadow: 0 -1px 0px #1a321a;\n}\n.art-video-player .hint--success.hint--top-left:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--top-right:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--top:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom-left:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom-right:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--left:before {\n border-left-color: #458746;\n}\n.art-video-player .hint--success.hint--right:before {\n border-right-color: #458746;\n}\n.art-video-player .hint--always:after,\n.art-video-player .hint--always:before {\n opacity: 1;\n visibility: visible;\n}\n.art-video-player .hint--always.hint--top:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top:after {\n -webkit-transform: translateX(-50%) translateY(-8px);\n -moz-transform: translateX(-50%) translateY(-8px);\n transform: translateX(-50%) translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-left:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-left:after {\n -webkit-transform: translateX(-100%) translateY(-8px);\n -moz-transform: translateX(-100%) translateY(-8px);\n transform: translateX(-100%) translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-right:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-right:after {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--bottom:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom:after {\n -webkit-transform: translateX(-50%) translateY(8px);\n -moz-transform: translateX(-50%) translateY(8px);\n transform: translateX(-50%) translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-left:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-left:after {\n -webkit-transform: translateX(-100%) translateY(8px);\n -moz-transform: translateX(-100%) translateY(8px);\n transform: translateX(-100%) translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-right:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-right:after {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--left:before {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--always.hint--left:after {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--always.hint--right:before {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--always.hint--right:after {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--rounded:after {\n border-radius: 4px;\n}\n.art-video-player .hint--no-animate:before,\n.art-video-player .hint--no-animate:after {\n -webkit-transition-duration: 0ms;\n -moz-transition-duration: 0ms;\n transition-duration: 0ms;\n}\n.art-video-player .hint--bounce:before,\n.art-video-player .hint--bounce:after {\n -webkit-transition: opacity 0.3s ease, visibility 0.3s ease, -webkit-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n -moz-transition: opacity 0.3s ease, visibility 0.3s ease, -moz-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n}\n.art-video-player .hint--no-shadow:before,\n.art-video-player .hint--no-shadow:after {\n text-shadow: initial;\n box-shadow: initial;\n}\n.art-video-player .hint--no-arrow:before {\n display: none;\n}\n.art-video-player.art-mobile {\n --art-bottom-gap: 10px;\n --art-control-height: 38px;\n --art-control-icon-scale: 1;\n --art-state-size: 60px;\n --art-settings-max-height: 180px;\n --art-selector-max-height: 180px;\n --art-indicator-scale: 1;\n --art-control-opacity: 1;\n}\n.art-video-player.art-mobile .art-controls-left {\n margin-left: calc(var(--art-padding) / -1);\n}\n.art-video-player.art-mobile .art-controls-right {\n margin-right: calc(var(--art-padding) / -1);\n}\n"; +const css = ".art-video-player {\n --art-theme: #f00;\n --art-font-color: #fff;\n --art-background-color: #000;\n --art-text-shadow-color: rgba(0, 0, 0, 0.5);\n --art-transition-duration: 0.2s;\n --art-padding: 10px;\n --art-border-radius: 3px;\n --art-progress-height: 6px;\n --art-progress-color: rgba(255, 255, 255, 0.25);\n --art-progress-top-gap: 10px;\n --art-hover-color: rgba(255, 255, 255, 0.25);\n --art-loaded-color: rgba(255, 255, 255, 0.25);\n --art-state-size: 80px;\n --art-state-opacity: 0.8;\n --art-bottom-height: 100px;\n --art-bottom-offset: 20px;\n --art-bottom-gap: 5px;\n --art-highlight-width: 8px;\n --art-highlight-color: rgba(255, 255, 255, 0.5);\n --art-control-height: 46px;\n --art-control-opacity: 0.75;\n --art-control-icon-size: 36px;\n --art-control-icon-scale: 1.1;\n --art-volume-height: 120px;\n --art-volume-handle-size: 14px;\n --art-lock-size: 36px;\n --art-indicator-scale: 0;\n --art-indicator-size: 16px;\n --art-fullscreen-web-index: 9999;\n --art-settings-icon-size: 24px;\n --art-settings-max-height: 300px;\n --art-selector-max-height: 300px;\n --art-contextmenus-min-width: 250px;\n --art-subtitle-font-size: 20px;\n --art-subtitle-gap: 5px;\n --art-subtitle-bottom: 15px;\n --art-subtitle-border: #000;\n --art-widget-background: rgba(0, 0, 0, 0.85);\n --art-tip-background: rgba(0, 0, 0, 0.7);\n --art-scrollbar-size: 4px;\n --art-scrollbar-background: rgba(255, 255, 255, 0.25);\n --art-scrollbar-background-hover: rgba(255, 255, 255, 0.5);\n --art-mini-progress-height: 2px;\n}\n.art-bg-cover {\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.art-bottom-gradient {\n background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0.4), transparent);\n background-repeat: repeat-x;\n background-position: center bottom;\n}\n.art-backdrop-filter {\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n backdrop-filter: saturate(180%) blur(20px);\n background-color: rgba(0, 0, 0, 0.75) !important;\n}\n.art-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.art-video-player {\n position: relative;\n margin: 0 auto;\n width: 100%;\n height: 100%;\n outline: 0;\n zoom: 1;\n padding: 0;\n text-align: left;\n direction: ltr;\n font-size: 14px;\n line-height: 1.3;\n user-select: none;\n box-sizing: border-box;\n color: var(--art-font-color);\n background-color: var(--art-background-color);\n text-shadow: 0 0 2px var(--art-text-shadow-color);\n font-family: PingFang SC, Helvetica Neue, Microsoft YaHei, Roboto, Arial, sans-serif;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n -ms-high-contrast-adjust: none;\n}\n.art-video-player *,\n.art-video-player *::before,\n.art-video-player *::after {\n box-sizing: border-box;\n}\n.art-video-player ::-webkit-scrollbar {\n width: var(--art-scrollbar-size);\n height: var(--art-scrollbar-size);\n}\n.art-video-player ::-webkit-scrollbar-thumb {\n background-color: var(--art-scrollbar-background);\n}\n.art-video-player ::-webkit-scrollbar-thumb:hover {\n background-color: var(--art-scrollbar-background-hover);\n}\n.art-video-player img {\n max-width: 100%;\n vertical-align: top;\n}\n.art-video-player svg {\n fill: var(--art-font-color);\n}\n.art-video-player a {\n color: var(--art-font-color);\n text-decoration: none;\n}\n.art-icon {\n line-height: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.art-video-player.art-backdrop .art-contextmenus,\n.art-video-player.art-backdrop .art-info,\n.art-video-player.art-backdrop .art-settings,\n.art-video-player.art-backdrop .art-layer-auto-playback,\n.art-video-player.art-backdrop .art-selector-list,\n.art-video-player.art-backdrop .art-volume-inner {\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n backdrop-filter: saturate(180%) blur(20px);\n background-color: rgba(0, 0, 0, 0.75) !important;\n}\n.art-video {\n position: absolute;\n inset: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n}\n.art-poster {\n position: absolute;\n inset: 0;\n z-index: 11;\n width: 100%;\n height: 100%;\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n pointer-events: none;\n}\n.art-video-player .art-subtitle {\n display: none;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n position: absolute;\n z-index: 20;\n width: 100%;\n padding: 0 5%;\n text-align: center;\n pointer-events: none;\n gap: var(--art-subtitle-gap);\n bottom: var(--art-subtitle-bottom);\n font-size: var(--art-subtitle-font-size);\n transition: bottom var(--art-transition-duration) ease;\n text-shadow: var(--art-subtitle-border) 1px 0 1px, var(--art-subtitle-border) 0 1px 1px, var(--art-subtitle-border) -1px 0 1px, var(--art-subtitle-border) 0 -1px 1px, var(--art-subtitle-border) 1px 1px 1px, var(--art-subtitle-border) -1px -1px 1px, var(--art-subtitle-border) 1px -1px 1px, var(--art-subtitle-border) -1px 1px 1px;\n}\n.art-video-player.art-subtitle-show .art-subtitle {\n display: flex;\n}\n.art-video-player.art-control-show .art-subtitle {\n bottom: calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom));\n}\n.art-danmuku {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: hidden;\n}\n.art-video-player .art-layers {\n position: absolute;\n inset: 0;\n z-index: 40;\n width: 100%;\n height: 100%;\n display: none;\n pointer-events: none;\n}\n.art-video-player .art-layers .art-layer {\n pointer-events: auto;\n}\n.art-video-player.art-layer-show .art-layers {\n display: flex;\n}\n.art-video-player .art-mask {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n inset: 0;\n z-index: 50;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-video-player .art-mask .art-state {\n display: flex;\n justify-content: center;\n align-items: center;\n opacity: 0;\n transform: scale(2);\n width: var(--art-state-size);\n height: var(--art-state-size);\n transition: all var(--art-transition-duration) ease;\n}\n.art-video-player.art-mask-show .art-state {\n pointer-events: auto;\n opacity: var(--art-state-opacity);\n transform: scale(1);\n}\n.art-video-player.art-loading-show .art-state {\n display: none;\n}\n.art-video-player .art-loading {\n display: none;\n justify-content: center;\n align-items: center;\n position: absolute;\n inset: 0;\n z-index: 70;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-video-player.art-loading-show .art-loading {\n display: flex;\n}\n.art-video-player.art-loading-show .art-mask {\n display: none;\n}\n.art-video-player .art-bottom {\n position: absolute;\n inset: 0;\n z-index: 60;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n padding: 0 var(--art-padding);\n transition: all var(--art-transition-duration) ease;\n background-size: 100% var(--art-bottom-height);\n background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0.4), transparent);\n background-repeat: repeat-x;\n background-position: center bottom;\n}\n.art-video-player .art-bottom .art-controls,\n.art-video-player .art-bottom .art-progress {\n transform: translateY(var(--art-bottom-offset));\n transition: transform var(--art-transition-duration) ease;\n}\n.art-video-player.art-control-show .art-bottom,\n.art-video-player.art-hover .art-bottom {\n opacity: 1;\n}\n.art-video-player.art-control-show .art-bottom .art-controls,\n.art-video-player.art-hover .art-bottom .art-controls,\n.art-video-player.art-control-show .art-bottom .art-progress,\n.art-video-player.art-hover .art-bottom .art-progress {\n transform: translateY(0);\n}\n.art-bottom .art-progress {\n position: relative;\n z-index: 0;\n cursor: pointer;\n pointer-events: auto;\n padding-top: var(--art-progress-top-gap);\n padding-bottom: var(--art-bottom-gap);\n}\n.art-bottom .art-progress .art-control-progress {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n height: var(--art-progress-height);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner {\n display: flex;\n align-items: center;\n position: relative;\n height: 50%;\n width: 100%;\n transition: height var(--art-transition-duration) ease;\n background-color: var(--art-progress-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-hover-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded {\n position: absolute;\n inset: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-loaded-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played {\n position: absolute;\n inset: 0;\n z-index: 20;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-theme);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n right: auto;\n pointer-events: auto;\n width: var(--art-highlight-width) !important;\n transform: translateX(calc(var(--art-highlight-width) / -2));\n background-color: var(--art-highlight-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n z-index: 40;\n left: 0;\n border-radius: 50%;\n width: var(--art-indicator-size);\n height: var(--art-indicator-size);\n transform: scale(var(--art-indicator-scale));\n margin-left: calc(var(--art-indicator-size) / -2);\n transition: transform var(--art-transition-duration) ease;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon {\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover {\n transform: scale(1.2) !important;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active {\n transform: scale(1) !important;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip {\n transform-origin: bottom center;\n transform: scale(0.5);\n opacity: 0;\n position: absolute;\n z-index: 50;\n top: -25px;\n left: 0;\n padding: 3px 5px;\n line-height: 1;\n font-size: 12px;\n border-radius: var(--art-border-radius);\n white-space: nowrap;\n background-color: var(--art-tip-background);\n transition: transform var(--art-transition-duration) ease, opacity var(--art-transition-duration) ease;\n}\n.art-bottom .art-progress .art-control-thumbnails {\n transform-origin: bottom center;\n transform: scale(0.5);\n opacity: 0;\n position: absolute;\n bottom: calc(var(--art-bottom-gap) + 10px);\n left: 0;\n border-radius: var(--art-border-radius);\n pointer-events: none;\n background-color: var(--art-widget-background);\n transition: transform var(--art-transition-duration) ease, opacity var(--art-transition-duration) ease;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 2px -1px rgba(0, 0, 0, 0.2);\n}\n.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner {\n height: 100%;\n}\n.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator {\n transform: scale(1);\n}\n.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,\n.art-progress-hover .art-bottom .art-progress .art-control-thumbnails {\n transform: scale(1);\n opacity: 1;\n}\n.art-video-player .art-controls {\n position: relative;\n z-index: 10;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n flex-shrink: 0;\n height: auto;\n min-height: var(--art-control-height);\n}\n.art-video-player .art-controls .art-controls-left,\n.art-video-player .art-controls .art-controls-right {\n display: flex;\n flex-wrap: wrap;\n max-width: 100%;\n min-height: var(--art-control-height);\n}\n.art-video-player .art-controls .art-controls-center {\n display: none;\n justify-content: center;\n align-items: center;\n flex: 1;\n height: 100%;\n padding: 0 10px;\n}\n.art-video-player .art-controls .art-controls-right {\n justify-content: flex-end;\n margin-left: auto;\n}\n.art-video-player .art-controls .art-control {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n max-width: 100%;\n cursor: pointer;\n white-space: nowrap;\n opacity: var(--art-control-opacity);\n min-height: var(--art-control-height);\n min-width: var(--art-control-height);\n transition: opacity var(--art-transition-duration) ease;\n}\n.art-video-player .art-controls .art-control .art-icon {\n height: var(--art-control-icon-size);\n width: var(--art-control-icon-size);\n transform: scale(var(--art-control-icon-scale));\n transition: transform var(--art-transition-duration) ease;\n}\n.art-video-player .art-controls .art-control .art-icon:active {\n transform: scale(calc(var(--art-control-icon-scale) * 0.8));\n}\n.art-video-player .art-controls .art-control:hover {\n opacity: 1;\n}\n.art-control-volume {\n position: relative;\n}\n.art-control-volume .art-volume-panel {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n left: 0;\n right: 0;\n padding: 0 5px;\n font-size: 12px;\n text-align: center;\n cursor: default;\n opacity: 0;\n visibility: hidden;\n transform: translateY(10px);\n pointer-events: none;\n bottom: var(--art-control-height);\n width: var(--art-control-height);\n height: var(--art-volume-height);\n transition: opacity var(--art-transition-duration) ease, transform var(--art-transition-duration) ease;\n}\n.art-control-volume .art-volume-panel .art-volume-inner {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 10px;\n height: 100%;\n width: 100%;\n padding: 10px 0 12px;\n border-radius: var(--art-border-radius);\n background-color: var(--art-widget-background);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider {\n flex: 1;\n width: 100%;\n display: flex;\n cursor: pointer;\n position: relative;\n justify-content: center;\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle {\n position: relative;\n display: flex;\n justify-content: center;\n width: 2px;\n border-radius: var(--art-border-radius);\n overflow: hidden;\n background-color: rgba(255, 255, 255, 0.25);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n background-color: var(--art-theme);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator {\n position: absolute;\n width: var(--art-volume-handle-size);\n height: var(--art-volume-handle-size);\n margin-top: calc(var(--art-volume-handle-size) / -2);\n flex-shrink: 0;\n transform: scale(1);\n border-radius: 100%;\n background-color: var(--art-theme);\n transition: transform var(--art-transition-duration) ease;\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator {\n transform: scale(0.9);\n}\n.art-control-volume:hover .art-volume-panel,\n.art-control-volume:focus-within .art-volume-panel {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n pointer-events: auto;\n}\n.art-video-player .art-notice {\n display: none;\n position: absolute;\n inset: 0;\n z-index: 80;\n width: 100%;\n height: 100%;\n height: auto;\n bottom: auto;\n padding: var(--art-padding);\n pointer-events: none;\n}\n.art-video-player .art-notice .art-notice-inner {\n display: inline-flex;\n padding: 5px;\n line-height: 1;\n border-radius: var(--art-border-radius);\n background-color: var(--art-tip-background);\n}\n.art-video-player.art-notice-show .art-notice {\n display: flex;\n}\n.art-video-player .art-contextmenus {\n display: none;\n flex-direction: column;\n position: absolute;\n z-index: 120;\n padding: 5px 0;\n border-radius: var(--art-border-radius);\n font-size: 12px;\n background-color: var(--art-widget-background);\n min-width: var(--art-contextmenus-min-width);\n}\n.art-video-player .art-contextmenus .art-contextmenu {\n cursor: pointer;\n display: flex;\n padding: 10px 15px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-contextmenus .art-contextmenu span {\n padding: 0 8px;\n}\n.art-video-player .art-contextmenus .art-contextmenu span:hover,\n.art-video-player .art-contextmenus .art-contextmenu span.art-current {\n color: var(--art-theme);\n}\n.art-video-player .art-contextmenus .art-contextmenu:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-contextmenus .art-contextmenu:last-child {\n border-bottom: none;\n}\n.art-video-player.art-contextmenu-show .art-contextmenus {\n display: flex;\n}\n.art-video-player .art-settings {\n display: none;\n flex-direction: column;\n position: absolute;\n z-index: 90;\n left: auto;\n overflow-y: auto;\n overflow-x: hidden;\n border-radius: var(--art-border-radius);\n max-height: var(--art-settings-max-height);\n right: var(--art-padding);\n bottom: var(--art-controls-height, var(--art-control-height));\n transition: all var(--art-transition-duration) ease;\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-settings .art-setting-panel {\n display: none;\n flex-direction: column;\n}\n.art-video-player .art-settings .art-setting-panel.art-current {\n display: flex;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 5px;\n padding: 0 5px;\n cursor: pointer;\n overflow: hidden;\n transition: background-color var(--art-transition-duration) ease;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current {\n color: var(--art-theme);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check {\n visibility: hidden;\n height: 15px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check {\n visibility: visible;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n gap: 5px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n height: var(--art-settings-icon-size);\n width: var(--art-settings-icon-size);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-width: 0;\n max-width: 55%;\n gap: 5px;\n font-size: 12px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(255, 255, 255, 0.5);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-width: 32px;\n height: 24px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range {\n height: 3px;\n width: 80px;\n outline: none;\n appearance: none;\n background-color: rgba(255, 255, 255, 0.2);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item-back {\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.art-video-player.art-setting-show .art-settings {\n display: flex;\n}\n.art-video-player .art-info {\n display: none;\n position: absolute;\n left: var(--art-padding);\n top: var(--art-padding);\n z-index: 100;\n padding: 10px;\n font-size: 12px;\n border-radius: var(--art-border-radius);\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-info .art-info-panel {\n display: flex;\n flex-direction: column;\n gap: 5px;\n}\n.art-video-player .art-info .art-info-panel .art-info-item {\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.art-video-player .art-info .art-info-panel .art-info-item .art-info-title {\n width: 100px;\n text-align: right;\n}\n.art-video-player .art-info .art-info-panel .art-info-item .art-info-content {\n width: 250px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n user-select: all;\n}\n.art-video-player .art-info .art-info-close {\n position: absolute;\n top: 5px;\n right: 5px;\n cursor: pointer;\n}\n.art-video-player.art-info-show .art-info {\n display: flex;\n}\n.art-hide-cursor * {\n cursor: none !important;\n}\n.art-video-player[data-aspect-ratio] {\n overflow: hidden;\n}\n.art-video-player[data-aspect-ratio] .art-video {\n object-fit: fill;\n box-sizing: content-box;\n}\n.art-fullscreen {\n --art-progress-height: 8px;\n --art-indicator-size: 20px;\n --art-control-height: 60px;\n --art-control-icon-scale: 1.3;\n}\n.art-fullscreen-web {\n --art-progress-height: 8px;\n --art-indicator-size: 20px;\n --art-control-height: 60px;\n --art-control-icon-scale: 1.3;\n position: fixed;\n inset: 0;\n z-index: var(--art-fullscreen-web-index);\n width: 100%;\n height: 100%;\n}\n.art-mini-popup {\n position: fixed;\n z-index: 9999;\n width: 320px;\n height: 180px;\n max-width: 100vw;\n max-height: 100vh;\n background: #000;\n border-radius: var(--art-border-radius);\n cursor: move;\n user-select: none;\n overflow: hidden;\n transition: opacity 0.2s ease;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);\n}\n.art-mini-popup svg {\n fill: #fff;\n}\n.art-mini-popup .art-video {\n pointer-events: none;\n}\n.art-mini-popup .art-mini-close {\n position: absolute;\n z-index: 20;\n right: 10px;\n top: 10px;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n.art-mini-popup .art-mini-state {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.2s ease;\n background-color: rgba(0, 0, 0, 0.25);\n}\n.art-mini-popup .art-mini-state .art-icon {\n opacity: 0.75;\n cursor: pointer;\n transform: scale(3);\n pointer-events: auto;\n transition: transform 0.2s ease;\n}\n.art-mini-popup .art-mini-state .art-icon:active {\n transform: scale(2.5);\n}\n.art-mini-popup.art-mini-dragging {\n opacity: 0.9;\n}\n.art-mini-popup:hover .art-mini-close,\n.art-mini-popup:focus-within .art-mini-close,\n.art-mini-popup:hover .art-mini-state,\n.art-mini-popup:focus-within .art-mini-state {\n opacity: 1;\n}\n.art-mini-popup [role='button']:focus-visible {\n outline: 2px solid #fff;\n outline-offset: -2px;\n}\n.art-video-player[data-flip='horizontal'] .art-video {\n transform: scaleX(-1);\n}\n.art-video-player[data-flip='vertical'] .art-video {\n transform: scaleY(-1);\n}\n.art-video-player .art-layer-lock {\n display: none;\n justify-content: center;\n align-items: center;\n position: absolute;\n top: 50%;\n border-radius: 50%;\n transform: translateY(-50%);\n height: var(--art-lock-size);\n width: var(--art-lock-size);\n left: var(--art-padding);\n background-color: var(--art-tip-background);\n}\n.art-video-player .art-layer-auto-playback {\n display: none;\n gap: 10px;\n align-items: center;\n position: absolute;\n border-radius: var(--art-border-radius);\n padding: 10px;\n line-height: 1;\n left: var(--art-padding);\n bottom: calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-close {\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-close svg {\n width: 15px;\n height: 15px;\n fill: var(--art-theme);\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-jump {\n color: var(--art-theme);\n cursor: pointer;\n}\n.art-video-player.art-lock .art-layer-lock {\n display: flex;\n}\n.art-video-player.art-lock:not(.art-control-show) .art-layer-lock {\n opacity: 0;\n pointer-events: none;\n}\n.art-video-player.art-lock:not(.art-control-show) .art-layer-lock:focus-within {\n opacity: 1;\n pointer-events: auto;\n}\n.art-video-player.art-lock .art-subtitle {\n bottom: var(--art-subtitle-bottom) !important;\n}\n.art-video-player.art-mini-progress-bar .art-bottom,\n.art-video-player.art-lock .art-bottom {\n opacity: 1;\n padding: 0;\n background-image: none;\n}\n.art-video-player.art-mini-progress-bar .art-bottom .art-controls,\n.art-video-player.art-lock .art-bottom .art-controls,\n.art-video-player.art-mini-progress-bar .art-bottom .art-progress,\n.art-video-player.art-lock .art-bottom .art-progress {\n transform: translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4));\n}\n.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,\n.art-video-player.art-lock .art-bottom .art-progress-indicator {\n display: none !important;\n}\n.art-video-player.art-control-show .art-layer-lock {\n display: flex;\n}\n.art-control-selector {\n position: relative;\n display: flex;\n justify-content: center;\n}\n.art-control-selector .art-selector-list {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n position: absolute;\n border-radius: var(--art-border-radius);\n overflow-y: auto;\n overflow-x: hidden;\n opacity: 0;\n visibility: hidden;\n transform: translateY(10px);\n pointer-events: none;\n bottom: var(--art-control-height);\n max-height: var(--art-selector-max-height);\n background-color: var(--art-widget-background);\n transition: opacity var(--art-transition-duration) ease, transform var(--art-transition-duration) ease;\n}\n.art-control-selector .art-selector-list .art-selector-item {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n padding: 10px 15px;\n flex-shrink: 0;\n line-height: 1;\n}\n.art-control-selector .art-selector-list .art-selector-item:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-control-selector .art-selector-list .art-selector-item:hover,\n.art-control-selector .art-selector-list .art-selector-item.art-current {\n color: var(--art-theme);\n}\n.art-control-selector:hover:not(.art-selector-dismissed) .art-selector-list,\n.art-control-selector.art-selector-open .art-selector-list {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n pointer-events: auto;\n}\n.art-video-player {\n /*! Hint.css - v2.7.0 - 2021-10-01\n * https://kushagra.dev/lab/hint/\n * Copyright (c) 2021 Kushagra Gour */\n /*-------------------------------------*\\\n HINT.css - A CSS tooltip library\n \\*-------------------------------------*/\n /**\n * HINT.css is a tooltip library made in pure CSS.\n *\n * Source: https://github.com/chinchang/hint.css\n * Demo: http://kushagragour.in/lab/hint/\n *\n */\n /**\n * source: hint-core.scss\n *\n * Defines the basic styling for the tooltip.\n * Each tooltip is made of 2 parts:\n * 1) body (:after)\n * 2) arrow (:before)\n *\n * Classes added:\n * 1) hint\n */\n /**\n * source: hint-position.scss\n *\n * Defines the positoning logic for the tooltips.\n *\n * Classes added:\n * 1) hint--top\n * 2) hint--bottom\n * 3) hint--left\n * 4) hint--right\n */\n /**\n * set default color for tooltip arrows\n */\n /**\n * top tooltip\n */\n /**\n * bottom tooltip\n */\n /**\n * right tooltip\n */\n /**\n * left tooltip\n */\n /**\n * top-left tooltip\n */\n /**\n * top-right tooltip\n */\n /**\n * bottom-left tooltip\n */\n /**\n * bottom-right tooltip\n */\n /**\n * source: hint-sizes.scss\n *\n * Defines width restricted tooltips that can span\n * across multiple lines.\n *\n * Classes added:\n * 1) hint--small\n * 2) hint--medium\n * 3) hint--large\n *\n */\n /**\n * source: hint-theme.scss\n *\n * Defines basic theme for tooltips.\n *\n */\n /**\n * source: hint-color-types.scss\n *\n * Contains tooltips of various types based on color differences.\n *\n * Classes added:\n * 1) hint--error\n * 2) hint--warning\n * 3) hint--info\n * 4) hint--success\n *\n */\n /**\n * Error\n */\n /**\n * Warning\n */\n /**\n * Info\n */\n /**\n * Success\n */\n /**\n * source: hint-always.scss\n *\n * Defines a persisted tooltip which shows always.\n *\n * Classes added:\n * 1) hint--always\n *\n */\n /**\n * source: hint-rounded.scss\n *\n * Defines rounded corner tooltips.\n *\n * Classes added:\n * 1) hint--rounded\n *\n */\n /**\n * source: hint-effects.scss\n *\n * Defines various transition effects for the tooltips.\n *\n * Classes added:\n * 1) hint--no-animate\n * 2) hint--bounce\n *\n */\n}\n.art-video-player [class*='hint--'] {\n position: relative;\n display: inline-block;\n font-style: normal;\n /**\n * tooltip arrow\n */\n /**\n * tooltip body\n */\n}\n.art-video-player [class*='hint--']:before,\n.art-video-player [class*='hint--']:after {\n position: absolute;\n -webkit-transform: translate3d(0, 0, 0);\n -moz-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n visibility: hidden;\n opacity: 0;\n z-index: 1000000;\n pointer-events: none;\n -webkit-transition: 0.3s ease;\n -moz-transition: 0.3s ease;\n transition: 0.3s ease;\n -webkit-transition-delay: 0ms;\n -moz-transition-delay: 0ms;\n transition-delay: 0ms;\n}\n.art-video-player [class*='hint--']:hover:before,\n.art-video-player [class*='hint--']:hover:after {\n visibility: visible;\n opacity: 1;\n}\n.art-video-player [class*='hint--']:hover:before,\n.art-video-player [class*='hint--']:hover:after {\n -webkit-transition-delay: 100ms;\n -moz-transition-delay: 100ms;\n transition-delay: 100ms;\n}\n.art-video-player [class*='hint--']:before {\n content: '';\n position: absolute;\n background: transparent;\n border: 6px solid transparent;\n z-index: 1000001;\n}\n.art-video-player [class*='hint--']:after {\n background: #000000;\n color: white;\n padding: 8px 10px;\n font-size: 12px;\n font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n line-height: 12px;\n white-space: nowrap;\n}\n.art-video-player [class*='hint--'][aria-label]:after {\n content: attr(aria-label);\n}\n.art-video-player [class*='hint--'][data-hint]:after {\n content: attr(data-hint);\n}\n.art-video-player [aria-label='']:before,\n.art-video-player [aria-label='']:after,\n.art-video-player [data-hint='']:before,\n.art-video-player [data-hint='']:after {\n display: none !important;\n}\n.art-video-player .hint--top-left:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--top-right:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--top:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--bottom-left:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--bottom-right:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--bottom:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--left:before {\n border-left-color: #000000;\n}\n.art-video-player .hint--right:before {\n border-right-color: #000000;\n}\n.art-video-player .hint--top:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top:before,\n.art-video-player .hint--top:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top:after {\n -webkit-transform: translateX(-50%);\n -moz-transform: translateX(-50%);\n transform: translateX(-50%);\n}\n.art-video-player .hint--top:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top:hover:after {\n -webkit-transform: translateX(-50%) translateY(-8px);\n -moz-transform: translateX(-50%) translateY(-8px);\n transform: translateX(-50%) translateY(-8px);\n}\n.art-video-player .hint--bottom:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom:before,\n.art-video-player .hint--bottom:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom:after {\n -webkit-transform: translateX(-50%);\n -moz-transform: translateX(-50%);\n transform: translateX(-50%);\n}\n.art-video-player .hint--bottom:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom:hover:after {\n -webkit-transform: translateX(-50%) translateY(8px);\n -moz-transform: translateX(-50%) translateY(8px);\n transform: translateX(-50%) translateY(8px);\n}\n.art-video-player .hint--right:before {\n margin-left: -11px;\n margin-bottom: -6px;\n}\n.art-video-player .hint--right:after {\n margin-bottom: -14px;\n}\n.art-video-player .hint--right:before,\n.art-video-player .hint--right:after {\n left: 100%;\n bottom: 50%;\n}\n.art-video-player .hint--right:hover:before {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--right:hover:after {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--left:before {\n margin-right: -11px;\n margin-bottom: -6px;\n}\n.art-video-player .hint--left:after {\n margin-bottom: -14px;\n}\n.art-video-player .hint--left:before,\n.art-video-player .hint--left:after {\n right: 100%;\n bottom: 50%;\n}\n.art-video-player .hint--left:hover:before {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--left:hover:after {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--top-left:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top-left:before,\n.art-video-player .hint--top-left:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top-left:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top-left:after {\n -webkit-transform: translateX(-100%);\n -moz-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n.art-video-player .hint--top-left:after {\n margin-left: 12px;\n}\n.art-video-player .hint--top-left:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top-left:hover:after {\n -webkit-transform: translateX(-100%) translateY(-8px);\n -moz-transform: translateX(-100%) translateY(-8px);\n transform: translateX(-100%) translateY(-8px);\n}\n.art-video-player .hint--top-right:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top-right:before,\n.art-video-player .hint--top-right:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top-right:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top-right:after {\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n transform: translateX(0);\n}\n.art-video-player .hint--top-right:after {\n margin-left: -12px;\n}\n.art-video-player .hint--top-right:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top-right:hover:after {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--bottom-left:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom-left:before,\n.art-video-player .hint--bottom-left:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom-left:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom-left:after {\n -webkit-transform: translateX(-100%);\n -moz-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n.art-video-player .hint--bottom-left:after {\n margin-left: 12px;\n}\n.art-video-player .hint--bottom-left:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom-left:hover:after {\n -webkit-transform: translateX(-100%) translateY(8px);\n -moz-transform: translateX(-100%) translateY(8px);\n transform: translateX(-100%) translateY(8px);\n}\n.art-video-player .hint--bottom-right:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom-right:before,\n.art-video-player .hint--bottom-right:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom-right:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom-right:after {\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n transform: translateX(0);\n}\n.art-video-player .hint--bottom-right:after {\n margin-left: -12px;\n}\n.art-video-player .hint--bottom-right:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom-right:hover:after {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--small:after,\n.art-video-player .hint--medium:after,\n.art-video-player .hint--large:after {\n white-space: normal;\n line-height: 1.4em;\n word-wrap: break-word;\n}\n.art-video-player .hint--small:after {\n width: 80px;\n}\n.art-video-player .hint--medium:after {\n width: 150px;\n}\n.art-video-player .hint--large:after {\n width: 300px;\n}\n.art-video-player [class*='hint--'] {\n /**\n * tooltip body\n */\n}\n.art-video-player [class*='hint--']:after {\n text-shadow: 0 -1px 0px black;\n box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);\n}\n.art-video-player .hint--error:after {\n background-color: #b34e4d;\n text-shadow: 0 -1px 0px #592726;\n}\n.art-video-player .hint--error.hint--top-left:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--top-right:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--top:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom-left:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom-right:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--left:before {\n border-left-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--right:before {\n border-right-color: #b34e4d;\n}\n.art-video-player .hint--warning:after {\n background-color: #c09854;\n text-shadow: 0 -1px 0px #6c5328;\n}\n.art-video-player .hint--warning.hint--top-left:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--top-right:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--top:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom-left:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom-right:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--left:before {\n border-left-color: #c09854;\n}\n.art-video-player .hint--warning.hint--right:before {\n border-right-color: #c09854;\n}\n.art-video-player .hint--info:after {\n background-color: #3986ac;\n text-shadow: 0 -1px 0px #1a3c4d;\n}\n.art-video-player .hint--info.hint--top-left:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--top-right:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--top:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom-left:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom-right:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--left:before {\n border-left-color: #3986ac;\n}\n.art-video-player .hint--info.hint--right:before {\n border-right-color: #3986ac;\n}\n.art-video-player .hint--success:after {\n background-color: #458746;\n text-shadow: 0 -1px 0px #1a321a;\n}\n.art-video-player .hint--success.hint--top-left:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--top-right:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--top:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom-left:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom-right:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--left:before {\n border-left-color: #458746;\n}\n.art-video-player .hint--success.hint--right:before {\n border-right-color: #458746;\n}\n.art-video-player .hint--always:after,\n.art-video-player .hint--always:before {\n opacity: 1;\n visibility: visible;\n}\n.art-video-player .hint--always.hint--top:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top:after {\n -webkit-transform: translateX(-50%) translateY(-8px);\n -moz-transform: translateX(-50%) translateY(-8px);\n transform: translateX(-50%) translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-left:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-left:after {\n -webkit-transform: translateX(-100%) translateY(-8px);\n -moz-transform: translateX(-100%) translateY(-8px);\n transform: translateX(-100%) translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-right:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-right:after {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--bottom:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom:after {\n -webkit-transform: translateX(-50%) translateY(8px);\n -moz-transform: translateX(-50%) translateY(8px);\n transform: translateX(-50%) translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-left:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-left:after {\n -webkit-transform: translateX(-100%) translateY(8px);\n -moz-transform: translateX(-100%) translateY(8px);\n transform: translateX(-100%) translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-right:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-right:after {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--left:before {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--always.hint--left:after {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--always.hint--right:before {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--always.hint--right:after {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--rounded:after {\n border-radius: 4px;\n}\n.art-video-player .hint--no-animate:before,\n.art-video-player .hint--no-animate:after {\n -webkit-transition-duration: 0ms;\n -moz-transition-duration: 0ms;\n transition-duration: 0ms;\n}\n.art-video-player .hint--bounce:before,\n.art-video-player .hint--bounce:after {\n -webkit-transition: opacity 0.3s ease, visibility 0.3s ease, -webkit-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n -moz-transition: opacity 0.3s ease, visibility 0.3s ease, -moz-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n}\n.art-video-player .hint--no-shadow:before,\n.art-video-player .hint--no-shadow:after {\n text-shadow: initial;\n box-shadow: initial;\n}\n.art-video-player .hint--no-arrow:before {\n display: none;\n}\n.art-video-player.art-mobile {\n --art-bottom-gap: 10px;\n --art-control-height: 38px;\n --art-control-icon-scale: 1;\n --art-state-size: 60px;\n --art-settings-max-height: 180px;\n --art-selector-max-height: 180px;\n --art-indicator-scale: 1;\n --art-control-opacity: 1;\n}\n.art-video-player.art-mobile .art-controls-left {\n margin-left: calc(var(--art-padding) / -1);\n}\n.art-video-player.art-mobile .art-controls-right {\n margin-right: calc(var(--art-padding) / -1);\n}\n.art-video-player [tabindex]:focus-visible,\n.art-video-player input:focus-visible,\n.art-video-player button:focus-visible,\n.art-video-player a:focus-visible {\n outline: 2px solid currentColor;\n outline-offset: -2px;\n}\n.art-video-player.art-keyboard-focus :focus {\n outline: 2px solid currentColor;\n outline-offset: -2px;\n}\n.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom {\n opacity: 1;\n}\n.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-controls,\n.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-progress {\n transform: translateY(0);\n}\n"; function parseSubtitle(buffer, option) { const text = new TextDecoder(option.encoding).decode(buffer); switch (option.type || getExt(option.url)) { diff --git a/docs/compiled/i18n/ar.js b/docs/compiled/i18n/ar.js index 56879d868..6bb90b887 100644 --- a/docs/compiled/i18n/ar.js +++ b/docs/compiled/i18n/ar.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nAr=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Video Info":"معلومات الفيديو",Close:"إغلاق","Video Load Failed":"فشل تحميل الفيديو",Volume:"الصوت",Play:"تشغيل",Pause:"إيقاف مؤقت",Rate:"السرعة",Mute:"كتم الصوت","Video Flip":"تدوير الفيديو",Horizontal:"أفقي",Vertical:"عمودي",Reconnect:"إعادة الاتصال","Show Setting":"إظهار الإعدادات","Hide Setting":"إخفاء الإعدادات",Screenshot:"لقطة شاشة","Play Speed":"سرعة التشغيل","Aspect Ratio":"نسبة العرض إلى الارتفاع",Default:"افتراضي",Normal:"عادي",Open:"فتح","Switch Video":"تبديل الفيديو","Switch Subtitle":"تبديل الترجمة",Fullscreen:"وضع ملء الشاشة","Exit Fullscreen":"الخروج من وضع ملء الشاشة","Web Fullscreen":"وضع ملء الشاشة في المتصفح","Exit Web Fullscreen":"الخروج من وضع ملء الشاشة في المتصفح","Mini Player":"مشغل صغير","PIP Mode":"الوضع العائم","Exit PIP Mode":"الخروج من الوضع العائم","PIP Not Supported":"الوضع العائم غير مدعوم","Fullscreen Not Supported":"وضع ملء الشاشة غير مدعوم","Subtitle Offset":"إزاحة الترجمة","Last Seen":"آخر مشاهدة","Jump Play":"التشغيل القافز",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay غير متاح"};return t("artplayer-i18n-ar",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nAr=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"قائمة السياق",Lock:"قفل",Back:"رجوع",Settings:"الإعدادات",Progress:"تقدم التشغيل","Video Info":"معلومات الفيديو",Close:"إغلاق","Video Load Failed":"فشل تحميل الفيديو",Volume:"الصوت",Play:"تشغيل",Pause:"إيقاف مؤقت",Rate:"السرعة",Mute:"كتم الصوت","Video Flip":"تدوير الفيديو",Horizontal:"أفقي",Vertical:"عمودي",Reconnect:"إعادة الاتصال","Show Setting":"إظهار الإعدادات","Hide Setting":"إخفاء الإعدادات",Screenshot:"لقطة شاشة","Play Speed":"سرعة التشغيل","Aspect Ratio":"نسبة العرض إلى الارتفاع",Default:"افتراضي",Normal:"عادي",Open:"فتح","Switch Video":"تبديل الفيديو","Switch Subtitle":"تبديل الترجمة",Fullscreen:"وضع ملء الشاشة","Exit Fullscreen":"الخروج من وضع ملء الشاشة","Web Fullscreen":"وضع ملء الشاشة في المتصفح","Exit Web Fullscreen":"الخروج من وضع ملء الشاشة في المتصفح","Mini Player":"مشغل صغير","PIP Mode":"الوضع العائم","Exit PIP Mode":"الخروج من الوضع العائم","PIP Not Supported":"الوضع العائم غير مدعوم","Fullscreen Not Supported":"وضع ملء الشاشة غير مدعوم","Subtitle Offset":"إزاحة الترجمة","Last Seen":"آخر مشاهدة","Jump Play":"التشغيل القافز",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay غير متاح"};return t("artplayer-i18n-ar",e),e})); diff --git a/docs/compiled/i18n/ar.mjs b/docs/compiled/i18n/ar.mjs index 0715c4758..e65ed2219 100644 --- a/docs/compiled/i18n/ar.mjs +++ b/docs/compiled/i18n/ar.mjs @@ -5,6 +5,11 @@ function i(e, t) { } } const o = { + "Context Menu": "قائمة السياق", + Lock: "قفل", + Back: "رجوع", + Settings: "الإعدادات", + Progress: "تقدم التشغيل", "Video Info": "معلومات الفيديو", Close: "إغلاق", "Video Load Failed": "فشل تحميل الفيديو", diff --git a/docs/compiled/i18n/cs.js b/docs/compiled/i18n/cs.js index e6f1c7098..990d835aa 100644 --- a/docs/compiled/i18n/cs.js +++ b/docs/compiled/i18n/cs.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nCs=e())})(this,(function(){"use strict";function t(o,i){if(typeof window<"u"){const n=window;n[o]=i}}const e={"Video Info":"Info o videu",Close:"Zavřít","Video Load Failed":"Nahrání videa selhalo",Volume:"Hlasitost",Play:"Přehrát",Pause:"Pozastavit",Rate:"Hodnocení",Mute:"Ztlumit","Video Flip":"Otočit video",Horizontal:"Horizontálně",Vertical:"Vertikálně",Reconnect:"Opětovné připojení","Show Setting":"Zobrazit nastavení","Hide Setting":"Skrýt nastavení",Screenshot:"Snímek obrazovky","Play Speed":"Rychlost přehrávání","Aspect Ratio":"Poměr stran",Default:"Výchozí",Normal:"Normální",Open:"Otevřít","Switch Video":"Přepnout video","Switch Subtitle":"Přepnout titulky",Fullscreen:"Celá obrazovka","Exit Fullscreen":"Opustit režim celé obrazovky","Web Fullscreen":"Celá stránka","Exit Web Fullscreen":"Zavřít režim celé stránky","Mini Player":"Mini přehrávač","PIP Mode":"Režim PIP","Exit PIP Mode":"Opustit režim PIP","PIP Not Supported":"Režim PIP není podporován","Fullscreen Not Supported":"Režim celé obrazovky není podporován","Subtitle Offset":"Posun titulků","Last Seen":"Naposledy viděn","Jump Play":"Hra na skok",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay není k dispozici"};return t("artplayer-i18n-cs",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nCs=e())})(this,(function(){"use strict";function t(o,n){if(typeof window<"u"){const i=window;i[o]=n}}const e={"Context Menu":"Kontextová nabídka",Lock:"Zamknout",Back:"Zpět",Settings:"Nastavení",Progress:"Průběh přehrávání","Video Info":"Info o videu",Close:"Zavřít","Video Load Failed":"Nahrání videa selhalo",Volume:"Hlasitost",Play:"Přehrát",Pause:"Pozastavit",Rate:"Hodnocení",Mute:"Ztlumit","Video Flip":"Otočit video",Horizontal:"Horizontálně",Vertical:"Vertikálně",Reconnect:"Opětovné připojení","Show Setting":"Zobrazit nastavení","Hide Setting":"Skrýt nastavení",Screenshot:"Snímek obrazovky","Play Speed":"Rychlost přehrávání","Aspect Ratio":"Poměr stran",Default:"Výchozí",Normal:"Normální",Open:"Otevřít","Switch Video":"Přepnout video","Switch Subtitle":"Přepnout titulky",Fullscreen:"Celá obrazovka","Exit Fullscreen":"Opustit režim celé obrazovky","Web Fullscreen":"Celá stránka","Exit Web Fullscreen":"Zavřít režim celé stránky","Mini Player":"Mini přehrávač","PIP Mode":"Režim PIP","Exit PIP Mode":"Opustit režim PIP","PIP Not Supported":"Režim PIP není podporován","Fullscreen Not Supported":"Režim celé obrazovky není podporován","Subtitle Offset":"Posun titulků","Last Seen":"Naposledy viděn","Jump Play":"Hra na skok",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay není k dispozici"};return t("artplayer-i18n-cs",e),e})); diff --git a/docs/compiled/i18n/cs.mjs b/docs/compiled/i18n/cs.mjs index d91cd5a05..8ad580eb6 100644 --- a/docs/compiled/i18n/cs.mjs +++ b/docs/compiled/i18n/cs.mjs @@ -1,10 +1,15 @@ -function i(e, t) { +function n(e, t) { if (typeof window < "u") { const o = window; o[e] = t; } } -const n = { +const i = { + "Context Menu": "Kontextová nabídka", + Lock: "Zamknout", + Back: "Zpět", + Settings: "Nastavení", + Progress: "Průběh přehrávání", "Video Info": "Info o videu", Close: "Zavřít", "Video Load Failed": "Nahrání videa selhalo", @@ -42,7 +47,7 @@ const n = { AirPlay: "AirPlay", "AirPlay Not Available": "AirPlay není k dispozici" }; -i("artplayer-i18n-cs", n); +n("artplayer-i18n-cs", i); export { - n as default + i as default }; diff --git a/docs/compiled/i18n/es.js b/docs/compiled/i18n/es.js index 9727a28e9..ce18e92d5 100644 --- a/docs/compiled/i18n/es.js +++ b/docs/compiled/i18n/es.js @@ -1 +1 @@ -(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nEs=e())})(this,(function(){"use strict";function a(o,t){if(typeof window<"u"){const l=window;l[o]=t}}const e={"Video Info":"Información del video",Close:"Cerrar","Video Load Failed":"Falló carga de video",Volume:"Volumen",Play:"Reproduciendo",Pause:"Pausa",Rate:"Velocidad",Mute:"Silencio","Video Flip":"Rotar video",Horizontal:"Horizontal",Vertical:"Vertical",Reconnect:"Reconectando","Show Setting":"Mostrar ajustes","Hide Setting":"Ocultar ajustes",Screenshot:"Captura de Pantalla","Play Speed":"Velocidad de reproducción","Aspect Ratio":"Relación de aspecto",Default:"Por defecto",Normal:"Normal",Open:"Abrir","Switch Video":"Cambiar video","Switch Subtitle":"Cambiar subtítulo",Fullscreen:"Pantalla completa","Exit Fullscreen":"Salir de Pantalla completa","Web Fullscreen":"Pantalla completa Web","Exit Web Fullscreen":"Salir de Pantalla completa","Mini Player":"Mini reproductor","PIP Mode":"Modo PiP","Exit PIP Mode":"Cerrar modo PiP","PIP Not Supported":"Modo PiP no compatible","Fullscreen Not Supported":"Pantalla completa no soportada","Subtitle Offset":"Ajuste subtítulo","Last Seen":"Visto última vez","Jump Play":"Saltar",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay no disponible"};return a("artplayer-i18n-es",e),e})); +(function(o,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self,o.artplayerI18nEs=e())})(this,(function(){"use strict";function o(a,t){if(typeof window<"u"){const i=window;i[a]=t}}const e={"Context Menu":"Menú contextual",Lock:"Bloquear",Back:"Volver",Settings:"Configuración",Progress:"Progreso de reproducción","Video Info":"Información del video",Close:"Cerrar","Video Load Failed":"Falló carga de video",Volume:"Volumen",Play:"Reproduciendo",Pause:"Pausa",Rate:"Velocidad",Mute:"Silencio","Video Flip":"Rotar video",Horizontal:"Horizontal",Vertical:"Vertical",Reconnect:"Reconectando","Show Setting":"Mostrar ajustes","Hide Setting":"Ocultar ajustes",Screenshot:"Captura de Pantalla","Play Speed":"Velocidad de reproducción","Aspect Ratio":"Relación de aspecto",Default:"Por defecto",Normal:"Normal",Open:"Abrir","Switch Video":"Cambiar video","Switch Subtitle":"Cambiar subtítulo",Fullscreen:"Pantalla completa","Exit Fullscreen":"Salir de Pantalla completa","Web Fullscreen":"Pantalla completa Web","Exit Web Fullscreen":"Salir de Pantalla completa","Mini Player":"Mini reproductor","PIP Mode":"Modo PiP","Exit PIP Mode":"Cerrar modo PiP","PIP Not Supported":"Modo PiP no compatible","Fullscreen Not Supported":"Pantalla completa no soportada","Subtitle Offset":"Ajuste subtítulo","Last Seen":"Visto última vez","Jump Play":"Saltar",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay no disponible"};return o("artplayer-i18n-es",e),e})); diff --git a/docs/compiled/i18n/es.mjs b/docs/compiled/i18n/es.mjs index 7e2c07bdf..e068ccbd7 100644 --- a/docs/compiled/i18n/es.mjs +++ b/docs/compiled/i18n/es.mjs @@ -5,6 +5,11 @@ function l(e, a) { } } const t = { + "Context Menu": "Menú contextual", + Lock: "Bloquear", + Back: "Volver", + Settings: "Configuración", + Progress: "Progreso de reproducción", "Video Info": "Información del video", Close: "Cerrar", "Video Load Failed": "Falló carga de video", diff --git a/docs/compiled/i18n/fa.js b/docs/compiled/i18n/fa.js index cd956a510..b28834810 100644 --- a/docs/compiled/i18n/fa.js +++ b/docs/compiled/i18n/fa.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nFa=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Video Info":"اطلاعات ویدیو",Close:"بستن","Video Load Failed":"بارگذاری ناموفق",Play:"پخش",Volume:"میزان صدا",Pause:"توقف",Rate:"نرخ",Mute:"سکوت","Video Flip":"چرخش تصویر",Horizontal:"افقی",Vertical:"عمودی",Reconnect:"اتصال مجدد","Show Setting":"تنظیمات","Hide Setting":"بستن تنظیمات",Screenshot:"عکس از صفحه","Play Speed":"سرعت پخش","Aspect Ratio":"نسبت تصویر",Default:"حالت پیشفرض",Normal:" حالت عادی",Open:"بازکردن","Switch Video":"تغییر ویدیو","Switch Subtitle":"نغییر زیرنویس",Fullscreen:"تمام صفحه","Exit Fullscreen":"کوچک کردن","Web Fullscreen":"حالت تئاتر","Exit Web Fullscreen":"خروج از حالت تئاتر","Mini Player":"حالت پخش کوچک","PIP Mode":" مینی پلیر","Exit PIP Mode":"خروج از مینی پلیر","PIP Not Supported":"عدم پشتیبانی از مینی پلیر","Fullscreen Not Supported":"عدم پشتیبانی از حالت تمام صفحه","Subtitle Offset":"افست زیرنویس","Last Seen":"آخرین بازدید","Jump Play":"جامپ پلی",AirPlay:"ایر پلی","AirPlay Not Available":"عدم پشتیبانی از ایرپلی"};return t("artplayer-i18n-fa",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nFa=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"منوی زمینه",Lock:"قفل",Back:"بازگشت",Settings:"تنظیمات",Progress:"پیشرفت پخش","Video Info":"اطلاعات ویدیو",Close:"بستن","Video Load Failed":"بارگذاری ناموفق",Play:"پخش",Volume:"میزان صدا",Pause:"توقف",Rate:"نرخ",Mute:"سکوت","Video Flip":"چرخش تصویر",Horizontal:"افقی",Vertical:"عمودی",Reconnect:"اتصال مجدد","Show Setting":"تنظیمات","Hide Setting":"بستن تنظیمات",Screenshot:"عکس از صفحه","Play Speed":"سرعت پخش","Aspect Ratio":"نسبت تصویر",Default:"حالت پیشفرض",Normal:" حالت عادی",Open:"بازکردن","Switch Video":"تغییر ویدیو","Switch Subtitle":"نغییر زیرنویس",Fullscreen:"تمام صفحه","Exit Fullscreen":"کوچک کردن","Web Fullscreen":"حالت تئاتر","Exit Web Fullscreen":"خروج از حالت تئاتر","Mini Player":"حالت پخش کوچک","PIP Mode":" مینی پلیر","Exit PIP Mode":"خروج از مینی پلیر","PIP Not Supported":"عدم پشتیبانی از مینی پلیر","Fullscreen Not Supported":"عدم پشتیبانی از حالت تمام صفحه","Subtitle Offset":"افست زیرنویس","Last Seen":"آخرین بازدید","Jump Play":"جامپ پلی",AirPlay:"ایر پلی","AirPlay Not Available":"عدم پشتیبانی از ایرپلی"};return t("artplayer-i18n-fa",e),e})); diff --git a/docs/compiled/i18n/fa.mjs b/docs/compiled/i18n/fa.mjs index dd354c207..d445c8f14 100644 --- a/docs/compiled/i18n/fa.mjs +++ b/docs/compiled/i18n/fa.mjs @@ -1,10 +1,15 @@ -function i(e, t) { +function o(e, t) { if (typeof window < "u") { const l = window; l[e] = t; } } -const o = { +const i = { + "Context Menu": "منوی زمینه", + Lock: "قفل", + Back: "بازگشت", + Settings: "تنظیمات", + Progress: "پیشرفت پخش", "Video Info": "اطلاعات ویدیو", Close: "بستن", "Video Load Failed": "بارگذاری ناموفق", @@ -42,7 +47,7 @@ const o = { AirPlay: "ایر پلی", "AirPlay Not Available": "عدم پشتیبانی از ایرپلی" }; -i("artplayer-i18n-fa", o); +o("artplayer-i18n-fa", i); export { - o as default + i as default }; diff --git a/docs/compiled/i18n/fr.js b/docs/compiled/i18n/fr.js index 23e16561b..2c491252c 100644 --- a/docs/compiled/i18n/fr.js +++ b/docs/compiled/i18n/fr.js @@ -1 +1 @@ -(function(i,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(i=typeof globalThis<"u"?globalThis:i||self,i.artplayerI18nFr=e())})(this,(function(){"use strict";function i(t,n){if(typeof window<"u"){const o=window;o[t]=n}}const e={"Video Info":"Informations de la vidéo",Close:"Fermer","Video Load Failed":"Téléchargement de la vidéo échoué",Volume:"Volume",Play:"Lire",Pause:"Pause",Rate:"Vitesse",Mute:"Muet","Video Flip":"Rotation de la vidéo",Horizontal:"Horizontal",Vertical:"Vertical",Reconnect:"Reconnexion","Show Setting":"Afficher les paramètres","Hide Setting":"Cacher les paramètres",Screenshot:"Capture d'écran","Play Speed":"Vitesse de lecture","Aspect Ratio":"Rapport d'aspect",Default:"Défaut",Normal:"Normal",Open:"Ouvrir","Switch Video":"Basculer la vidéo","Switch Subtitle":"Basculer le sous-titre",Fullscreen:"Plein écran","Exit Fullscreen":"Quitter le plein écran","Web Fullscreen":"Plein écran Web","Exit Web Fullscreen":"Quitter le plein écran Web","Mini Player":"Mini lecteur","PIP Mode":"Mode PiP","Exit PIP Mode":"Fermer le mode PiP","PIP Not Supported":"Mode PiP non supporté","Fullscreen Not Supported":"Plein écran non supporté","Subtitle Offset":"Réglage des sous-titres","Last Seen":"Dernière position","Jump Play":"Continuer",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay non disponible"};return i("artplayer-i18n-fr",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nFr=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"Menu contextuel",Lock:"Verrouiller",Back:"Retour",Settings:"Paramètres",Progress:"Progression de lecture","Video Info":"Informations de la vidéo",Close:"Fermer","Video Load Failed":"Téléchargement de la vidéo échoué",Volume:"Volume",Play:"Lire",Pause:"Pause",Rate:"Vitesse",Mute:"Muet","Video Flip":"Rotation de la vidéo",Horizontal:"Horizontal",Vertical:"Vertical",Reconnect:"Reconnexion","Show Setting":"Afficher les paramètres","Hide Setting":"Cacher les paramètres",Screenshot:"Capture d'écran","Play Speed":"Vitesse de lecture","Aspect Ratio":"Rapport d'aspect",Default:"Défaut",Normal:"Normal",Open:"Ouvrir","Switch Video":"Basculer la vidéo","Switch Subtitle":"Basculer le sous-titre",Fullscreen:"Plein écran","Exit Fullscreen":"Quitter le plein écran","Web Fullscreen":"Plein écran Web","Exit Web Fullscreen":"Quitter le plein écran Web","Mini Player":"Mini lecteur","PIP Mode":"Mode PiP","Exit PIP Mode":"Fermer le mode PiP","PIP Not Supported":"Mode PiP non supporté","Fullscreen Not Supported":"Plein écran non supporté","Subtitle Offset":"Réglage des sous-titres","Last Seen":"Dernière position","Jump Play":"Continuer",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay non disponible"};return t("artplayer-i18n-fr",e),e})); diff --git a/docs/compiled/i18n/fr.mjs b/docs/compiled/i18n/fr.mjs index 29c134a75..45fe9a61f 100644 --- a/docs/compiled/i18n/fr.mjs +++ b/docs/compiled/i18n/fr.mjs @@ -1,10 +1,15 @@ -function l(e, i) { +function i(e, t) { if (typeof window < "u") { - const t = window; - t[e] = i; + const r = window; + r[e] = t; } } const o = { + "Context Menu": "Menu contextuel", + Lock: "Verrouiller", + Back: "Retour", + Settings: "Paramètres", + Progress: "Progression de lecture", "Video Info": "Informations de la vidéo", Close: "Fermer", "Video Load Failed": "Téléchargement de la vidéo échoué", @@ -42,7 +47,7 @@ const o = { AirPlay: "AirPlay", "AirPlay Not Available": "AirPlay non disponible" }; -l("artplayer-i18n-fr", o); +i("artplayer-i18n-fr", o); export { o as default }; diff --git a/docs/compiled/i18n/id.js b/docs/compiled/i18n/id.js index 96bdc9828..83ffa844a 100644 --- a/docs/compiled/i18n/id.js +++ b/docs/compiled/i18n/id.js @@ -1 +1 @@ -(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nId=e())})(this,(function(){"use strict";function a(i,t){if(typeof window<"u"){const n=window;n[i]=t}}const e={"Video Info":"Informasi Video",Close:"Tutup","Video Load Failed":"Gagal Memuat Video",Volume:"Volume",Play:"Putar",Pause:"Jeda",Rate:"Kecepatan",Mute:"Senyap","Video Flip":"Memutar Video",Horizontal:"Horizontal",Vertical:"Vertikal",Reconnect:"Menyambung Kembali","Show Setting":"Tampilkan Pengaturan","Hide Setting":"Sembunyikan Pengaturan",Screenshot:"Tangkapan Layar","Play Speed":"Kecepatan Putar","Aspect Ratio":"Rasio Aspek",Default:"Default",Normal:"Normal",Open:"Buka","Switch Video":"Ganti Video","Switch Subtitle":"Ganti Subtitle",Fullscreen:"Layar Penuh","Exit Fullscreen":"Keluar dari Layar Penuh","Web Fullscreen":"Layar Penuh Web","Exit Web Fullscreen":"Keluar dari Layar Penuh Web","Mini Player":"Pemutar Mini","PIP Mode":"Mode PIP","Exit PIP Mode":"Keluar dari Mode PIP","PIP Not Supported":"PIP Tidak Didukung","Fullscreen Not Supported":"Layar Penuh Tidak Didukung","Subtitle Offset":"Pergeseran Subtitle","Last Seen":"Terakhir Dilihat","Jump Play":"Lompat Putar",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay Tidak Tersedia"};return a("artplayer-i18n-id",e),e})); +(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nId=e())})(this,(function(){"use strict";function a(i,n){if(typeof window<"u"){const t=window;t[i]=n}}const e={"Context Menu":"Menu konteks",Lock:"Kunci",Back:"Kembali",Settings:"Pengaturan",Progress:"Progres pemutaran","Video Info":"Informasi Video",Close:"Tutup","Video Load Failed":"Gagal Memuat Video",Volume:"Volume",Play:"Putar",Pause:"Jeda",Rate:"Kecepatan",Mute:"Senyap","Video Flip":"Memutar Video",Horizontal:"Horizontal",Vertical:"Vertikal",Reconnect:"Menyambung Kembali","Show Setting":"Tampilkan Pengaturan","Hide Setting":"Sembunyikan Pengaturan",Screenshot:"Tangkapan Layar","Play Speed":"Kecepatan Putar","Aspect Ratio":"Rasio Aspek",Default:"Default",Normal:"Normal",Open:"Buka","Switch Video":"Ganti Video","Switch Subtitle":"Ganti Subtitle",Fullscreen:"Layar Penuh","Exit Fullscreen":"Keluar dari Layar Penuh","Web Fullscreen":"Layar Penuh Web","Exit Web Fullscreen":"Keluar dari Layar Penuh Web","Mini Player":"Pemutar Mini","PIP Mode":"Mode PIP","Exit PIP Mode":"Keluar dari Mode PIP","PIP Not Supported":"PIP Tidak Didukung","Fullscreen Not Supported":"Layar Penuh Tidak Didukung","Subtitle Offset":"Pergeseran Subtitle","Last Seen":"Terakhir Dilihat","Jump Play":"Lompat Putar",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay Tidak Tersedia"};return a("artplayer-i18n-id",e),e})); diff --git a/docs/compiled/i18n/id.mjs b/docs/compiled/i18n/id.mjs index 9f09df5a8..734cf6378 100644 --- a/docs/compiled/i18n/id.mjs +++ b/docs/compiled/i18n/id.mjs @@ -5,6 +5,11 @@ function t(e, a) { } } const n = { + "Context Menu": "Menu konteks", + Lock: "Kunci", + Back: "Kembali", + Settings: "Pengaturan", + Progress: "Progres pemutaran", "Video Info": "Informasi Video", Close: "Tutup", "Video Load Failed": "Gagal Memuat Video", diff --git a/docs/compiled/i18n/pl.js b/docs/compiled/i18n/pl.js index dd8775b71..b2a81a4d5 100644 --- a/docs/compiled/i18n/pl.js +++ b/docs/compiled/i18n/pl.js @@ -1 +1 @@ -(function(i,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(i=typeof globalThis<"u"?globalThis:i||self,i.artplayerI18nPl=e())})(this,(function(){"use strict";function i(n,o){if(typeof window<"u"){const t=window;t[n]=o}}const e={"Video Info":"Informacje o wideo",Close:"Zamknij","Video Load Failed":"Błąd ładowania wideo",Volume:"Głośność",Play:"Odtwórz",Pause:"Wstrzymaj",Rate:"Oceń",Mute:"Wycisz","Video Flip":"Rotacja wideo",Horizontal:"Pozioma",Vertical:"Pionowa",Reconnect:"Połącz ponownie","Show Setting":"Pokaż ustawienia","Hide Setting":"Ukryj ustawienia",Screenshot:"Zrzut ekranu","Play Speed":"Prędkość odtwarzania","Aspect Ratio":"Współczynnik proporcji",Default:"Domyślny",Normal:"Normalny",Open:"Otwórz","Switch Video":"Przełącz wideo","Switch Subtitle":"Przełącz napisy",Fullscreen:"Pełny ekran","Exit Fullscreen":"Zamknij pełny ekran","Web Fullscreen":"Tryb pełnej strony","Exit Web Fullscreen":"Zamknij tryb pełnej strony","Mini Player":"Miniodtwarzacz","PIP Mode":"Tryb PiP","Exit PIP Mode":"Zamknij tryb PiP","PIP Not Supported":"Tryb PiP nieobsługiwany","Fullscreen Not Supported":"Pełny ekran nieobsługiwany","Subtitle Offset":"Przesunięcie napisów","Last Seen":"Ostatnio widziany","Jump Play":"Skocz do gry",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay nie jest dostępny"};return i("artplayer-i18n-pl",e),e})); +(function(n,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(n=typeof globalThis<"u"?globalThis:n||self,n.artplayerI18nPl=e())})(this,(function(){"use strict";function n(i,o){if(typeof window<"u"){const t=window;t[i]=o}}const e={"Context Menu":"Menu kontekstowe",Lock:"Zablokuj",Back:"Wstecz",Settings:"Ustawienia",Progress:"Postęp odtwarzania","Video Info":"Informacje o wideo",Close:"Zamknij","Video Load Failed":"Błąd ładowania wideo",Volume:"Głośność",Play:"Odtwórz",Pause:"Wstrzymaj",Rate:"Oceń",Mute:"Wycisz","Video Flip":"Rotacja wideo",Horizontal:"Pozioma",Vertical:"Pionowa",Reconnect:"Połącz ponownie","Show Setting":"Pokaż ustawienia","Hide Setting":"Ukryj ustawienia",Screenshot:"Zrzut ekranu","Play Speed":"Prędkość odtwarzania","Aspect Ratio":"Współczynnik proporcji",Default:"Domyślny",Normal:"Normalny",Open:"Otwórz","Switch Video":"Przełącz wideo","Switch Subtitle":"Przełącz napisy",Fullscreen:"Pełny ekran","Exit Fullscreen":"Zamknij pełny ekran","Web Fullscreen":"Tryb pełnej strony","Exit Web Fullscreen":"Zamknij tryb pełnej strony","Mini Player":"Miniodtwarzacz","PIP Mode":"Tryb PiP","Exit PIP Mode":"Zamknij tryb PiP","PIP Not Supported":"Tryb PiP nieobsługiwany","Fullscreen Not Supported":"Pełny ekran nieobsługiwany","Subtitle Offset":"Przesunięcie napisów","Last Seen":"Ostatnio widziany","Jump Play":"Skocz do gry",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay nie jest dostępny"};return n("artplayer-i18n-pl",e),e})); diff --git a/docs/compiled/i18n/pl.mjs b/docs/compiled/i18n/pl.mjs index 5d48a1fc0..3e6273784 100644 --- a/docs/compiled/i18n/pl.mjs +++ b/docs/compiled/i18n/pl.mjs @@ -5,6 +5,11 @@ function o(e, i) { } } const a = { + "Context Menu": "Menu kontekstowe", + Lock: "Zablokuj", + Back: "Wstecz", + Settings: "Ustawienia", + Progress: "Postęp odtwarzania", "Video Info": "Informacje o wideo", Close: "Zamknij", "Video Load Failed": "Błąd ładowania wideo", diff --git a/docs/compiled/i18n/ru.js b/docs/compiled/i18n/ru.js index 7ae10b89e..518569d17 100644 --- a/docs/compiled/i18n/ru.js +++ b/docs/compiled/i18n/ru.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nRu=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Video Info":"Информация",Close:"Закрыть","Video Load Failed":"Ошибка загрузки видео",Volume:"Громкость",Play:"Играть",Pause:"Пауза",Rate:"Скорость",Mute:"Заглушить","Video Flip":"Развернуть видео",Horizontal:"Горизонтально",Vertical:"Вертикально",Reconnect:"Переподключенине","Show Setting":"Показать настройки","Hide Setting":"Скрыть настройки",Screenshot:"Скриншот","Play Speed":"Скорость воспроизведения","Aspect Ratio":"Соотношение сторон",Default:"По-умолчанию",Normal:"Нормальный",Open:"Открыть","Switch Video":"Переключить видео","Switch Subtitle":"Переключить субтитры",Fullscreen:"Полноэкранный режим","Exit Fullscreen":"Выход из полноэкранного режима","Web Fullscreen":"На все окно браузера","Exit Web Fullscreen":"Выход из режима полного окна","Mini Player":"Мини проигрыватель","PIP Mode":"Картинка в картинке","Exit PIP Mode":"Закрыть картинку в картинке","PIP Not Supported":"Картинка в картинке не поддерживается","Fullscreen Not Supported":"Полноэкранный режим не поддерживается","Subtitle Offset":"Настройка субтитров","Last Seen":"Последнее просмотренное","Jump Play":"Перейти",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay недоступен"};return t("artplayer-i18n-ru",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nRu=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"Контекстное меню",Lock:"Заблокировать",Back:"Назад",Settings:"Настройки",Progress:"Ход воспроизведения","Video Info":"Информация",Close:"Закрыть","Video Load Failed":"Ошибка загрузки видео",Volume:"Громкость",Play:"Играть",Pause:"Пауза",Rate:"Скорость",Mute:"Заглушить","Video Flip":"Развернуть видео",Horizontal:"Горизонтально",Vertical:"Вертикально",Reconnect:"Переподключенине","Show Setting":"Показать настройки","Hide Setting":"Скрыть настройки",Screenshot:"Скриншот","Play Speed":"Скорость воспроизведения","Aspect Ratio":"Соотношение сторон",Default:"По-умолчанию",Normal:"Нормальный",Open:"Открыть","Switch Video":"Переключить видео","Switch Subtitle":"Переключить субтитры",Fullscreen:"Полноэкранный режим","Exit Fullscreen":"Выход из полноэкранного режима","Web Fullscreen":"На все окно браузера","Exit Web Fullscreen":"Выход из режима полного окна","Mini Player":"Мини проигрыватель","PIP Mode":"Картинка в картинке","Exit PIP Mode":"Закрыть картинку в картинке","PIP Not Supported":"Картинка в картинке не поддерживается","Fullscreen Not Supported":"Полноэкранный режим не поддерживается","Subtitle Offset":"Настройка субтитров","Last Seen":"Последнее просмотренное","Jump Play":"Перейти",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay недоступен"};return t("artplayer-i18n-ru",e),e})); diff --git a/docs/compiled/i18n/ru.mjs b/docs/compiled/i18n/ru.mjs index 5ec8e27e7..641c37043 100644 --- a/docs/compiled/i18n/ru.mjs +++ b/docs/compiled/i18n/ru.mjs @@ -5,6 +5,11 @@ function i(e, t) { } } const o = { + "Context Menu": "Контекстное меню", + Lock: "Заблокировать", + Back: "Назад", + Settings: "Настройки", + Progress: "Ход воспроизведения", "Video Info": "Информация", Close: "Закрыть", "Video Load Failed": "Ошибка загрузки видео", diff --git a/docs/compiled/i18n/tr.js b/docs/compiled/i18n/tr.js index fd2100d60..105ec3125 100644 --- a/docs/compiled/i18n/tr.js +++ b/docs/compiled/i18n/tr.js @@ -1 +1 @@ -(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nTr=e())})(this,(function(){"use strict";function a(n,i){if(typeof window<"u"){const t=window;t[n]=i}}const e={"Video Info":"Video Bilgisi",Close:"Kapat","Video Load Failed":"Video Yüklenemedi",Volume:"Ses Seviyesi",Play:"Oynat",Pause:"Duraklat",Rate:"Hız",Mute:"Sessize Al","Video Flip":"Videoyu Çevir",Horizontal:"Yatay",Vertical:"Dikey",Reconnect:"Yeniden Bağlan","Show Setting":"Ayarları Göster","Hide Setting":"Ayarları Gizle",Screenshot:"Ekran Görüntüsü","Play Speed":"Oynatma Hızı","Aspect Ratio":"En Boy Oranı",Default:"Varsayılan",Normal:"Normal",Open:"Aç","Switch Video":"Video Değiştir","Switch Subtitle":"Altyazı Değiştir",Fullscreen:"Tam Ekran","Exit Fullscreen":"Tam Ekrandan Çık","Web Fullscreen":"Web Tam Ekran","Exit Web Fullscreen":"Web Tam Ekranından Çık","Mini Player":"Küçük Oynatıcı","PIP Mode":"PIP Modu","Exit PIP Mode":"PIP Modundan Çık","PIP Not Supported":"PIP Desteklenmiyor","Fullscreen Not Supported":"Tam Ekran Desteklenmiyor","Subtitle Offset":"Altyazı Kaydırma","Last Seen":"Son İzlenen","Jump Play":"Atla ve Oynat",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay Kullanılamıyor"};return a("artplayer-i18n-tr",e),e})); +(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nTr=e())})(this,(function(){"use strict";function a(n,i){if(typeof window<"u"){const t=window;t[n]=i}}const e={"Context Menu":"Bağlam menüsü",Lock:"Kilitle",Back:"Geri",Settings:"Ayarlar",Progress:"Oynatma ilerlemesi","Video Info":"Video Bilgisi",Close:"Kapat","Video Load Failed":"Video Yüklenemedi",Volume:"Ses Seviyesi",Play:"Oynat",Pause:"Duraklat",Rate:"Hız",Mute:"Sessize Al","Video Flip":"Videoyu Çevir",Horizontal:"Yatay",Vertical:"Dikey",Reconnect:"Yeniden Bağlan","Show Setting":"Ayarları Göster","Hide Setting":"Ayarları Gizle",Screenshot:"Ekran Görüntüsü","Play Speed":"Oynatma Hızı","Aspect Ratio":"En Boy Oranı",Default:"Varsayılan",Normal:"Normal",Open:"Aç","Switch Video":"Video Değiştir","Switch Subtitle":"Altyazı Değiştir",Fullscreen:"Tam Ekran","Exit Fullscreen":"Tam Ekrandan Çık","Web Fullscreen":"Web Tam Ekran","Exit Web Fullscreen":"Web Tam Ekranından Çık","Mini Player":"Küçük Oynatıcı","PIP Mode":"PIP Modu","Exit PIP Mode":"PIP Modundan Çık","PIP Not Supported":"PIP Desteklenmiyor","Fullscreen Not Supported":"Tam Ekran Desteklenmiyor","Subtitle Offset":"Altyazı Kaydırma","Last Seen":"Son İzlenen","Jump Play":"Atla ve Oynat",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay Kullanılamıyor"};return a("artplayer-i18n-tr",e),e})); diff --git a/docs/compiled/i18n/tr.mjs b/docs/compiled/i18n/tr.mjs index 3fd6fda66..6df0c887f 100644 --- a/docs/compiled/i18n/tr.mjs +++ b/docs/compiled/i18n/tr.mjs @@ -4,7 +4,12 @@ function l(e, a) { i[e] = a; } } -const n = { +const t = { + "Context Menu": "Bağlam menüsü", + Lock: "Kilitle", + Back: "Geri", + Settings: "Ayarlar", + Progress: "Oynatma ilerlemesi", "Video Info": "Video Bilgisi", Close: "Kapat", "Video Load Failed": "Video Yüklenemedi", @@ -42,7 +47,7 @@ const n = { AirPlay: "AirPlay", "AirPlay Not Available": "AirPlay Kullanılamıyor" }; -l("artplayer-i18n-tr", n); +l("artplayer-i18n-tr", t); export { - n as default + t as default }; diff --git a/docs/compiled/i18n/vi.js b/docs/compiled/i18n/vi.js index 5e2fedf11..02ae6c912 100644 --- a/docs/compiled/i18n/vi.js +++ b/docs/compiled/i18n/vi.js @@ -1 +1 @@ -(function(t,n){typeof exports=="object"&&typeof module<"u"?module.exports=n():typeof define=="function"&&define.amd?define(n):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nVi=n())})(this,(function(){"use strict";function t(e,i){if(typeof window<"u"){const h=window;h[e]=i}}const n={"Video Info":"Thông tin video",Close:"Đóng","Video Load Failed":"Tải video thất bại",Volume:"Âm lượng",Play:"Phát",Pause:"Tạm dừng",Rate:"Tốc độ",Mute:"Tắt tiếng","Video Flip":"Lật video",Horizontal:"Ngang",Vertical:"Dọc",Reconnect:"Kết nối lại","Show Setting":"Cài đặt","Hide Setting":"Ẩn cài đặt",Screenshot:"Chụp màn hình","Play Speed":"Tốc độ phát","Aspect Ratio":"Tỷ lệ khung hình",Default:"Mặc định",Normal:"Bình thường",Open:"Mở","Switch Video":"Chuyển video","Switch Subtitle":"Chuyển phụ đề",Fullscreen:"Toàn màn hình","Exit Fullscreen":"Thoát toàn màn hình","Web Fullscreen":"Toàn màn hình trình duyệt","Exit Web Fullscreen":"Thoát toàn màn hình trình duyệt","Mini Player":"Trình phát mini","PIP Mode":"Phát trong hình","Exit PIP Mode":"Thoát phát trong hình","PIP Not Supported":"Không hỗ trợ phát trong hình","Fullscreen Not Supported":"Không hỗ trợ toàn màn hình","Subtitle Offset":"Độ trễ phụ đề","Last Seen":"Lần xem cuối","Jump Play":"Nhảy đến đoạn phát",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay không khả dụng"};return t("artplayer-i18n-vi",n),n})); +(function(t,n){typeof exports=="object"&&typeof module<"u"?module.exports=n():typeof define=="function"&&define.amd?define(n):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nVi=n())})(this,(function(){"use strict";function t(e,i){if(typeof window<"u"){const h=window;h[e]=i}}const n={"Context Menu":"Menu ngữ cảnh",Lock:"Khóa",Back:"Quay lại",Settings:"Cài đặt",Progress:"Tiến trình phát","Video Info":"Thông tin video",Close:"Đóng","Video Load Failed":"Tải video thất bại",Volume:"Âm lượng",Play:"Phát",Pause:"Tạm dừng",Rate:"Tốc độ",Mute:"Tắt tiếng","Video Flip":"Lật video",Horizontal:"Ngang",Vertical:"Dọc",Reconnect:"Kết nối lại","Show Setting":"Cài đặt","Hide Setting":"Ẩn cài đặt",Screenshot:"Chụp màn hình","Play Speed":"Tốc độ phát","Aspect Ratio":"Tỷ lệ khung hình",Default:"Mặc định",Normal:"Bình thường",Open:"Mở","Switch Video":"Chuyển video","Switch Subtitle":"Chuyển phụ đề",Fullscreen:"Toàn màn hình","Exit Fullscreen":"Thoát toàn màn hình","Web Fullscreen":"Toàn màn hình trình duyệt","Exit Web Fullscreen":"Thoát toàn màn hình trình duyệt","Mini Player":"Trình phát mini","PIP Mode":"Phát trong hình","Exit PIP Mode":"Thoát phát trong hình","PIP Not Supported":"Không hỗ trợ phát trong hình","Fullscreen Not Supported":"Không hỗ trợ toàn màn hình","Subtitle Offset":"Độ trễ phụ đề","Last Seen":"Lần xem cuối","Jump Play":"Nhảy đến đoạn phát",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay không khả dụng"};return t("artplayer-i18n-vi",n),n})); diff --git a/docs/compiled/i18n/vi.mjs b/docs/compiled/i18n/vi.mjs index 697bbcc38..2f4ecbae4 100644 --- a/docs/compiled/i18n/vi.mjs +++ b/docs/compiled/i18n/vi.mjs @@ -5,6 +5,11 @@ function h(n, t) { } } const i = { + "Context Menu": "Menu ngữ cảnh", + Lock: "Khóa", + Back: "Quay lại", + Settings: "Cài đặt", + Progress: "Tiến trình phát", "Video Info": "Thông tin video", Close: "Đóng", "Video Load Failed": "Tải video thất bại", diff --git a/docs/compiled/i18n/zh-tw.js b/docs/compiled/i18n/zh-tw.js index 3048834cf..0f57e24c1 100644 --- a/docs/compiled/i18n/zh-tw.js +++ b/docs/compiled/i18n/zh-tw.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nZhTw=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Video Info":"統計訊息",Close:"關閉","Video Load Failed":"載入失敗",Volume:"音量",Play:"播放",Pause:"暫停",Rate:"速度",Mute:"靜音","Video Flip":"畫面翻轉",Horizontal:"水平",Vertical:"垂直",Reconnect:"重新連接","Show Setting":"顯示设置","Hide Setting":"隱藏设置",Screenshot:"截圖","Play Speed":"播放速度","Aspect Ratio":"畫面比例",Default:"默認",Normal:"正常",Open:"打開","Switch Video":"切換","Switch Subtitle":"切換字幕",Fullscreen:"全屏","Exit Fullscreen":"退出全屏","Web Fullscreen":"網頁全屏","Exit Web Fullscreen":"退出網頁全屏","Mini Player":"迷你播放器","PIP Mode":"開啟畫中畫","Exit PIP Mode":"退出畫中畫","PIP Not Supported":"不支持畫中畫","Fullscreen Not Supported":"不支持全屏","Subtitle Offset":"字幕偏移","Last Seen":"上次看到","Jump Play":"跳轉播放",AirPlay:"隔空播放","AirPlay Not Available":"隔空播放不可用"};return t("artplayer-i18n-zh-tw",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nZhTw=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"快捷選單",Lock:"鎖定",Back:"返回",Settings:"設定",Progress:"播放進度","Video Info":"統計訊息",Close:"關閉","Video Load Failed":"載入失敗",Volume:"音量",Play:"播放",Pause:"暫停",Rate:"速度",Mute:"靜音","Video Flip":"畫面翻轉",Horizontal:"水平",Vertical:"垂直",Reconnect:"重新連接","Show Setting":"顯示设置","Hide Setting":"隱藏设置",Screenshot:"截圖","Play Speed":"播放速度","Aspect Ratio":"畫面比例",Default:"默認",Normal:"正常",Open:"打開","Switch Video":"切換","Switch Subtitle":"切換字幕",Fullscreen:"全屏","Exit Fullscreen":"退出全屏","Web Fullscreen":"網頁全屏","Exit Web Fullscreen":"退出網頁全屏","Mini Player":"迷你播放器","PIP Mode":"開啟畫中畫","Exit PIP Mode":"退出畫中畫","PIP Not Supported":"不支持畫中畫","Fullscreen Not Supported":"不支持全屏","Subtitle Offset":"字幕偏移","Last Seen":"上次看到","Jump Play":"跳轉播放",AirPlay:"隔空播放","AirPlay Not Available":"隔空播放不可用"};return t("artplayer-i18n-zh-tw",e),e})); diff --git a/docs/compiled/i18n/zh-tw.mjs b/docs/compiled/i18n/zh-tw.mjs index b20c8dc69..f32c2f5a1 100644 --- a/docs/compiled/i18n/zh-tw.mjs +++ b/docs/compiled/i18n/zh-tw.mjs @@ -1,10 +1,15 @@ -function i(e, t) { +function o(e, t) { if (typeof window < "u") { const l = window; l[e] = t; } } -const o = { +const i = { + "Context Menu": "快捷選單", + Lock: "鎖定", + Back: "返回", + Settings: "設定", + Progress: "播放進度", "Video Info": "統計訊息", Close: "關閉", "Video Load Failed": "載入失敗", @@ -42,7 +47,7 @@ const o = { AirPlay: "隔空播放", "AirPlay Not Available": "隔空播放不可用" }; -i("artplayer-i18n-zh-tw", o); +o("artplayer-i18n-zh-tw", i); export { - o as default + i as default }; diff --git a/package.json b/package.json index 04322b475..3f701a961 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "ci:build": "yarn build:types && yarn build all && yarn build:i18n && yarn build:ts && yarn build:docs && yarn test:imports", "test:imports": "node --test test/esm.test.js test/i18n.test.js test/ssr.test.js", "typecheck": "node scripts/typecheck.mjs", - "test:unit": "node --test test/playback.test.js test/dash-control.test.js test/public-behavior.test.js test/helpers.test.js test/chapter.test.js test/utils.test.js test/resource-scope.test.js test/instance-lifecycle.test.js test/options.test.js test/media-hosts.test.js test/plugins.test.js test/source.test.js test/playback-properties.test.js test/media-events.test.js test/template-resources.test.js test/core-vendor.test.js test/component-resources.test.js test/setting-model.test.js test/setting-layout.test.js test/setting-resources.test.js test/subtitle.test.js test/display-native.test.js test/display-video-fullscreen.test.js test/display-pip.test.js test/display-mini.test.js test/display-sizing.test.js test/display-orientation.test.js test/hotkey.test.js test/listener-registry.test.js test/global-events.test.js test/pointer-events.test.js test/gesture.test.js test/event-scheduling.test.js test/notice.test.js test/fast-forward.test.js test/auto-playback.test.js test/builtin-layers.test.js test/prompt-components.test.js test/screenshot.test.js test/thumbnails.test.js test/progress.test.js test/environment.test.js test/storage.test.js test/facade-properties.test.js test/dom-boundaries.test.js test/initialization.test.js test/entry.test.js", + "test:unit": "node --test test/playback.test.js test/dash-control.test.js test/public-behavior.test.js test/helpers.test.js test/chapter.test.js test/utils.test.js test/resource-scope.test.js test/instance-lifecycle.test.js test/options.test.js test/media-hosts.test.js test/plugins.test.js test/source.test.js test/playback-properties.test.js test/media-events.test.js test/template-resources.test.js test/core-vendor.test.js test/component-resources.test.js test/setting-model.test.js test/setting-layout.test.js test/setting-resources.test.js test/subtitle.test.js test/display-native.test.js test/display-video-fullscreen.test.js test/display-pip.test.js test/display-mini.test.js test/display-sizing.test.js test/display-orientation.test.js test/hotkey.test.js test/listener-registry.test.js test/global-events.test.js test/pointer-events.test.js test/gesture.test.js test/event-scheduling.test.js test/notice.test.js test/fast-forward.test.js test/auto-playback.test.js test/builtin-layers.test.js test/prompt-components.test.js test/screenshot.test.js test/thumbnails.test.js test/progress.test.js test/environment.test.js test/storage.test.js test/facade-properties.test.js test/dom-boundaries.test.js test/initialization.test.js test/entry.test.js test/accessibility-button.test.js test/accessibility-focus.test.js test/accessibility-slider.test.js", "test": "yarn test:node && yarn test:baseline", "test:browser": "playwright test", "test:browser:install": "playwright install chromium firefox webkit", diff --git a/packages/artplayer/ARCHITECTURE.md b/packages/artplayer/ARCHITECTURE.md index e43d52dbe..e979e487a 100644 --- a/packages/artplayer/ARCHITECTURE.md +++ b/packages/artplayer/ARCHITECTURE.md @@ -1279,3 +1279,228 @@ intentional defect corrections from preserved behavior. For timers or Blob URLs, also identify the owner and verify cleanup in the consuming module. Remaining ecosystem declaration work, accessibility and release validation are recorded in refactor/tasks.json and should extend this map as they land. + +## Keyboard interaction ownership + +`accessibility/button.ts` makes the existing control nodes keyboard-operable without +replacing their DOM or pointer click callbacks. Enter activates on keydown; Space +activates on keyup only if the same enabled control retained focus. Repeats, blur, +modifier/composition input and disposed scopes cannot activate an armed action. +Listeners belong to the existing component entry scope. `accessibility/keyboard.ts` +records handled events in a WeakSet so Hotkey can retain generic keydown delivery +without performing a second Space action. Unrelated prevented events retain the +historical hotkey policy. Native button/summary and ARIA button/switch activation, +and Enter on links, are reserved for those elements; unrelated custom keys remain. + +Play/pause uses its stable control wrapper and changes its accessible name with +the existing media events. Volume keeps its original icon and panel hierarchy; +both icon buttons use the localized Mute name and aria-pressed, transferring focus +only when the previously focused icon becomes hidden. This leaves the volume panel +outside a button's accessibility subtree. Setting, fullscreen/web-fullscreen, PiP, +AirPlay and screenshot buttons reuse existing tooltip names and click paths. Custom +controls with option.click receive the same behavior unless their supplied content +already contains interactive elements, whose native behavior is preserved. + +`accessibility/focus.ts` owns keyboard/pointer modality and the additive +art-keyboard-focus class. The control auto-hide predicate keeps keyboard-focused +content visible, while pointer focus keeps its original hiding behavior. Root +listeners survive DOM moves; document listeners rebind on focus in a new ownerDocument +and release the old document. All listeners and the class release with the bottom +entry scope. Native focus updates existing isFocus/isInput flags without emitting +extra public pointer focus/blur events. `style/accessibility.less` supplies visible +focus and keyboard control-bar visibility without changing existing class hooks. + +`accessibility/slider.ts` owns range keyboard input and ARIA state. Arrow keys use +the configured step, PageUp/PageDown use ten steps, and Home/End select endpoints. +Unavailable or non-finite ranges remain focusable but disabled; their navigation +keys cannot fall through to player shortcuts. Values and accessible text follow +the actual media properties, including native seek rounding. + +`control/progress/keyboard.ts` binds the range to the existing progress entry, +separately from pointer dragging. It emits the existing setBar payload before seek, +omitting the optional pointer event. Entry disposal, source changes or a newer +nested keyboard action cancel the pending seek. Native metadata, seeking and time +events refresh the range. Volume uses the same helper on the existing slider +outside the mute buttons. Keyboard adjustment unmutes and then writes volume, +unless the muted callback disposed the entry or started a newer action. + +The volume panel becomes visible on focus within the control. Only opacity and +transform animate: delaying visibility can make rapid Tab navigation skip its +slider. Mouse hover remains supported and keyboard visibility does not prevent +the existing pointer auto-hide policy. The additive Progress translation exists +in all twelve shipped dictionaries; its public type is optional so complete old +dictionaries remain assignable. Regenerate types and Monaco declarations together. + +Run the accessibility-button/accessibility-focus/accessibility-slider unit tests and +`yarn test:browser accessibility hotkey progress-quality` +when changing these boundaries. Tests use actual Tab/Enter/Space input and media, +including Firefox's pre-existing native video Tab stop, one-action semantics, +native nested buttons, pointer hiding, replacement and disposal. Slider coverage +includes real media seek/volume, fast Tab, unavailable metadata, localization and +callback cancellation alongside old progress dragging. CORE-23 still owns +settings-tree, dynamic control focus, mode-exit and full accessibility acceptance; these focused checks +are not whole-player accessibility certification. + +`control/selector-keyboard.ts` owns the selector popup's keyboard focus and +visibility. The existing value opens with Enter/Space/Up/Down. The current option +receives focus; arrows, Home/End and typed prefixes move focus without selecting. +Enter/Space call the existing item click path, preserving the onSelect receiver, +item/node identity and click event. Escape dismisses the popup and returns focus +to its value; Tab leaves without committing. Hover remains a separate input path. +Only the component entry scope owns these listeners and popup classes. + +Ordinary selector lists expose listbox/options with aria-selected. Caller-supplied +interactive option HTML uses a group instead so native buttons/inputs retain their +semantics and editing keys. Native buttons in the value become the trigger instead +of being nested inside a new button role. Selection and async returned HTML refresh +that binding. Focus lost only because the focused value child was replaced is +restored to the new trigger; callbacks that deliberately focus elsewhere retain +that focus. Caller-supplied interactive content still needs its own accessible names. + +The existing selector generation and trackSelection guards remain responsible for +async result ownership. Keyboard navigation does not change those generations; +committing a real click does. Changing this boundary requires both +accessibility-selector and the existing components/progress-quality browser tests, +including reusing selector objects, rejecting async callbacks, updating controls, +removing entries and preserving old property-descriptor flags. + +`setting/keyboard.ts` owns panel entry, arrow navigation, Escape and focusout; +`setting/keyboard-item.ts` adds row activation, switch state and native range names; +`setting/keyboard-focus.ts` selects visible targets and restores focus after panel +navigation, replacement, rollback or removal. These helpers respect paused item +and panel scopes. Native inputs retain editing keys; nested native buttons retain +their click behavior. Tab exit checks actual focus in a scope-owned zero-delay +task, since a microtask can observe body during the browser's focus transition. +Pointer opening does not move focus into the panel. Existing click callbacks and +selection/update generations remain the mutation boundaries. + +`accessibility/moved-focus.ts` restores a connected focused node when moving the +player for web fullscreen makes the browser focus body. It never overrides focus +deliberately assigned elsewhere and is not used during destruction cleanup. Mode +code rechecks cancellation after focus callbacks before publishing notifications. +Back and Settings names are optional public i18n fields with generated package +and Monaco declarations; keep all shipped dictionaries synchronized. + +Progress keyboard seeks reuse `source/restore-position.ts` for one bounded +correction when an outstanding native end seek overwrites the latest position. +The initial operation uses the existing seek setter and setBar-before-seek order; +the correction writes currentTime without another public seek notification. The +pending operation belongs to both the control entry and current source. A newer +keyboard action, public position write, source replacement, removal or destruction +supersedes it. Never turn this into indefinite retries or overwrite manual input. +Validate this boundary with accessibility-slider and source unit/browser tests; +settings and moved-focus changes also require accessibility-setting and display-web. + +`component/focus.ts` restores control focus at the end of remove/update. An update +owns one focus transaction, so its internal remove does not first focus a neighbor. +Prefer the replacement entry, then surviving following/preceding controls; preserve +focus explicitly assigned outside by beforeUnmount/mounted callbacks. Failed mounts +can restore to a neighbor, while a beforeUnmount veto leaves the original focused +node intact. Native descendants, disabled fieldsets, hidden entries and inert trees +must be evaluated as actual focus targets. A selector option may be the removed +focused descendant even though the replacement is an ordinary button. + +If no control survives, `accessibility/player-focus.ts` gives the connected player +programmatic focus using tabindex=-1. Keep that owned attribute until instance +cleanup: removing it immediately after focus blurs the player in Chromium. It adds +no sequential Tab stop and preserves caller-supplied tabindex values. Focus recovery +is skipped during destruction and for unrelated instances. Run accessibility-controls +alongside components, settings, selectors, sliders and Hotkey after changing this +boundary; keep Component/Control's historical return values and failure behavior. + +`display/mini-focus.ts` captures a mini session's originating player element and +restores it only when closing would hide the current popup focus. Keyboard entry +focuses Close; pointer/programmatic entry keeps external focus. If the origin was +removed, hidden, disabled or made inert, use the player focus fallback. Starting a +new session outside the player clears stale origins. Mini revision checks still +surround focus callbacks, so reentry or destruction cancels obsolete notifications. + +The owned mini view makes its existing Close and stable playback wrapper keyboard +buttons. Playback activation calls the existing visible icon's click handler, so +native media playback, pause and public events retain their paths. Escape is owned +only while the popup is active. Names reuse Close, Mini Player, Play and Pause from +i18n; the wrapper name follows actual playback. Focus within reveals the existing +hover controls and focus-visible supplies an outline. Custom caller-owned mini DOM +keeps its own controls, structure and styling; no fresh-view button binding is added +to it. Destroy releases owned listeners without attempting to restore focus. + +Run accessibility-mini with display-mini, display-web, the other accessibility +scenarios and Hotkey. Check real Tab/Enter/Space/Escape, playback, repeated entry, +external/removed focus origins, hidden controls, and destroy during restored focus; +the older drag, DOM order, restore-failure and supplied-popup tests remain required. + +`info/keyboard.ts` installs the close button, panel Escape and visibility-driven +focus restoration inside the existing polling scope. Keyboard opening focuses +Close; pointer/programmatic visibility preserves unrelated focus. The originating +player element survives repeated init calls, while each init replaces listeners. +Closing restores a connected visible origin or the player fallback. An optional +SSR info wrapper may be absent: skip wrapper-dependent keyboard behavior while +retaining the historical poll and click close path. Info keeps its existing class +fields and prototype; failed initialization and manual destroy release keyboard +resources together with polling. Close and Video Info reuse existing i18n keys. + +`plugins/lock-keyboard.ts` binds the existing lock layer as a stable toggle button, +with aria-pressed and Escape to unlock. The existing state setter and click path +still own class/flag/event ordering. Its entry scope owns a temporary control-bar +focus suspension. `accessibility/suspend-focus.ts` uses inert/aria-hidden plus saved +tabindex values, so Tab exclusion also works without native inert. Child additions +are observed, moved-out nodes regain their tabindex, and unlock/removal/destruction +restore owned attributes without overwriting different caller values. + +Keyboard focus no longer overrides the locked control-bar transform. A locked +layer whose controls are hidden stays a Tab target while visually hidden; focus +reveals it through the existing control visibility behavior. Lock is an optional +public i18n field with twelve dictionary translations; regenerate package and +Monaco declarations together. Test accessibility-info/accessibility-lock alongside +prompt-components, builtin-layers, other keyboard controls and Hotkey, including +failed init, absent SSR wrapper, dynamic controls and focus-attribute ownership. +When remounting the lock layer while already locked, initialize its icons from the +actual current state along with aria-pressed and the new focus scope; defaulting +the visible icon to unlocked would contradict the still-active public state. + +`contextmenu/keyboard.ts` binds Shift+F10 and ContextMenu to the existing menu, +then owns arrow/Home/End navigation, typeahead, Escape, Tab exit and focus return. +The container is a named group; action rows are buttons and choice rows contain +individual buttons. Native links, buttons and editable custom HTML retain their +roles and activation. Opening uses the focused element's viewport rectangle with +the same positioning rules as pointer opening, extracted to contextmenu/position.ts. +Editable input context gestures remain native; the static CONTEXTMENU switch +disables both player opening paths. Pointer opening does not acquire focus. + +`contextmenu/choices.ts` adds keyboard activation and aria-pressed to the existing +data-value spans, retaining click targets, art-current highlighting and property +events. Custom row callbacks keep their old arguments, this, return values and +responsibility for closing the menu. Component focus recovery covers contextmenu +as well as control: replacement first, then following/preceding visible DOM entries. +Initialization replaces root listeners only after entries were successfully added; +a duplicate-entry error preserves the old bindings. Entry and instance scopes own +all listeners and the deferred focusout check; destruction never restores focus. + +`accessibility/overlay-focus.ts` tracks menu origins in a WeakMap. Info and mini +resolve an origin through it before an action closes the menu, so closing the next +panel can return to the original control rather than a hidden menu item. This does +not pre-focus another node or change the existing menu callback/event sequence. +Closing skips removed, hidden, disabled or inert origins, uses the player fallback, +and preserves deliberate external focus transfers. Context Menu is an optional +public translation key; update all dictionaries and regenerate both declaration views. + +Run accessibility-contextmenu with accessibility, components, prompt-components, +display-mini and hotkey. Cover real keyboard entry, one activation, choice rows, +callback focus/destruction, repeated init, editable HTML, cross-player focus, +Info/mini handoff and menu positioning. Browser automation does not certify screen +reader speech, native system context menus or physical mobile keyboard behavior. + +Setting navigation excludes hidden, disabled (including fieldsets) and inert +targets. `setting/keyboard-focus.ts` also owns exit fallback when a plugin removes, +hides, disables or moves the setting button while the panel is open. Only focus +still inside the closing panel is transferred; an external callback keeps its focus. + +Run accessibility-integration for native fullscreen entry/exit with actual keyboard +gestures, browser-initiated fullscreen exit, and PiP with the native capability +attachment. Unsupported PiP environments verify the existing notice/focus fallback; +they are not successful native PiP sessions. SSR tests retain player/video/subtitle +node identities, load actual WebVTT cues, toggle them from a custom keyboard control +and check web fullscreen focus and caption visibility. Subtitles retain their +existing passive rendering without adding Tab stops or continuous live announcements. +Physical Apple presentation surfaces and assistive technology remain release-review +checks; no simulated adapter is counted as those devices. diff --git a/packages/artplayer/dist/artplayer.cts b/packages/artplayer/dist/artplayer.cts new file mode 100644 index 000000000..4693bc06d --- /dev/null +++ b/packages/artplayer/dist/artplayer.cts @@ -0,0 +1,29 @@ +import type * as Definition from './artplayer.js' + +declare const Artplayer: typeof Definition.default +// eslint-disable-next-line ts/no-redeclare -- CJS constructor value and instance type share the export. +type Artplayer = Definition.default + +// eslint-disable-next-line ts/no-redeclare, ts/no-namespace -- Namespace merging carries named types on the existing CJS export. +declare namespace Artplayer { + type Config = Definition.Config + type Emitter> = Definition.Emitter + type Events = Definition.Events + type I18n = Definition.I18n + type Icons = Definition.Icons + type Option = Definition.Option + type OptionInput = Definition.OptionInput + type Player = Definition.Player + type PlaybackControls = Definition.PlaybackControls + type PluginFactory = Definition.PluginFactory + type Plugins = Definition.Plugins + type Setting = Definition.Setting + type SettingOption = Definition.SettingOption + type Subtitle = Definition.Subtitle + type SubtitleUpdateEvents = Definition.SubtitleUpdateEvents + type Template = Definition.Template + type Utils = Definition.Utils +} + +// eslint-disable-next-line no-restricted-syntax -- Preserve the real CommonJS constructor export. +export = Artplayer diff --git a/packages/artplayer/dist/artplayer.js b/packages/artplayer/dist/artplayer.js index bd3ed2efa..a433c0626 100644 --- a/packages/artplayer/dist/artplayer.js +++ b/packages/artplayer/dist/artplayer.js @@ -67,4 +67,4 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),l=/^(?:(?!chrome|android).)*safari/i.test(s),c=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=c||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,p=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,u="undefined"!==typeof window&&"undefined"!==typeof document;const h={properties:["audioTracks","autoplay","buffered","controller","controls","crossOrigin","currentSrc","currentTime","defaultMuted","defaultPlaybackRate","duration","ended","error","loop","mediaGroup","muted","networkState","paused","playbackRate","played","preload","readyState","seekable","seeking","src","startDate","textTracks","videoTracks","volume"],methods:["addTextTrack","canPlayType","load","play","pause"],events:["abort","canplay","canplaythrough","durationchange","emptied","ended","error","loadeddata","loadedmetadata","loadstart","pause","play","playing","progress","ratechange","seeked","seeking","stalled","suspend","timeupdate","volumechange","waiting"],prototypes:["width","height","videoWidth","videoHeight","poster","webkitDecodedFrameCount","webkitDroppedFrameCount","playsInline","webkitSupportsFullscreen","webkitDisplayingFullscreen","onenterpictureinpicture","onleavepictureinpicture","disablePictureInPicture","cancelVideoFrameCallback","requestVideoFrameCallback","getVideoPlaybackQuality","requestPictureInPicture","webkitEnterFullScreen","webkitEnterFullscreen","webkitExitFullScreen","webkitExitFullscreen"]};class f extends Error{constructor(t){super("Failed to release ArtPlayer resources"),this.errors=t,this.name="ResourceCleanupError"}}class m{constructor(){this.cleanups=new Set,this.disposed=!1}get closed(){return this.disposed}add(t){let e=!0;const r=()=>{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new m,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof f?t.push(...e.errors):t.push(e)}if(t.length)throw new f(t)}}const g=new WeakMap,v=new WeakMap;function y(t){const e=g.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function b(t){return y(t).scope}function w(t){const e=y(t);return e.destroying||e.scope.closed}function x(t,e,r,n,o=!1){const i=y(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],s=t=>{try{t()}catch(e){a.push(...e instanceof f?e.errors:[e])}};n&&t.template?.$video&&s(()=>t.reset()),s(()=>i.scope.dispose()),s(()=>(t.template||i.mountingTemplate)?.destroy(r));const l=e.indexOf(t);-1!==l&&e.splice(l,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),s(()=>t.emit("destroy")),s(()=>i.finalizers.dispose()),o&&i.rollback&&s(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const c of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",c);if(a.length)throw a[0]}const k=new WeakMap;function $(t,e){const r=b(t).child();return k.set(e,r),r}function E(t){const e=k.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function T(t){k.get(t)?.dispose()}function C(t,e,r,n){const o=E(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function L(t,e){return{on:(r,n)=>{C(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=E(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}function S(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode??null;return"undefined"===typeof window||e.includes(window)||e.push(window),e}function P(t,e){return S(t).includes(e)}function M(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function z(t){return t.getBoundingClientRect()}function A(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;";try{document.body.appendChild(t);const e=getComputedStyle(t);return{top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0}}finally{t.remove()}}function R(t,e=document){return e.querySelector(t)}function O(t,e){return t.classList.add(e)}function I(t,e){return t.classList.remove(e)}function N(t,e){return t.classList.contains(e)}function _(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function W(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function D(t,e){W(t).forEach(t=>I(t,e)),O(t,e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function V(t){return document.createElement(t)}function Y(t,e,r="top"){p||(t.setAttribute("aria-label",e),O(t,"hint--rounded"),O(t,`hint--${r}`))}function B(t="",e=""){const r=V("i");return O(r,"art-icon"),O(r,`art-icon-${t}`),_(r,e),r}function H(t,e,r){return t.style[e]=r,t}function j(t,e){for(const r in e)H(t,r,e[r]);return t}function q(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new m;let a=!1,s=()=>{};function l(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function c(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void c(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;d(l,()=>c(l)),i.closed||(l.src=e)}catch(e){l(e)}}))}),i.closed||(n.src=t)}catch(p){l(p)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(p){l(p)}},e.onerror=()=>l(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}class U extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function X(t,e){if(!t)throw new U(e);return t}function G(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function K(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function Z(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function J(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function Q(t){return t.charAt(0).toUpperCase()+t.slice(1)}function tt(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const et={"&":"&","<":"<",">":">","'":"'",'"':"""},rt={"&":"&","<":"<",">":">","'":"'",""":'"'},nt=/(&|<|>|'|")/g;function ot(t){return t.replace(/[&<>'"]/g,t=>et[t]||t)}const it=Object.defineProperty,{hasOwnProperty:at}=Object.prototype;function st(t,e){return at.call(t,e)}function lt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function ct(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?ct(o,i):i,it(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function dt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function pt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function ut(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const ht=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:U,addClass:O,append:_,assToVtt:ut,capitalize:Q,clamp:J,createElement:V,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:it,download:Z,errorHandle:X,escape:ot,get:lt,getComposedPath:S,getExt:K,getIcon:B,getRect:z,getSafeAreaInsets:A,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:N,includeFromEvent:P,inverseClass:D,isBrowser:u,isIOS:c,isIOS13:d,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:p,isSafari:l,loadImg:function(t,e){return q(t,e,void 0)},mergeDeep:ct,query:R,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:I,replaceElement:F,secondToTime:tt,setStyle:H,setStyleText:a,setStyles:j,siblings:W,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:M,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:Y,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:s,vttToBlob:pt},Symbol.toStringTag,{value:"Module"}));function ft(t,e){return _(t,e)}function mt(t,e){return e.querySelector(t)}const gt="array",vt="boolean",yt="string",bt="number",wt="object",xt="function";function kt(t,e,r){return X(e===yt||e===bt||t instanceof Element,`${r.join(".")} require '${yt}' or 'Element' type`)}const $t={html:kt,disable:`?${vt}`,name:`?${yt}`,index:`?${bt}`,style:`?${wt}`,click:`?${xt}`,mounted:`?${xt}`,tooltip:`?${yt}|${bt}`,width:`?${bt}`,selector:`?${gt}`,onSelect:`?${xt}`,switch:`?${vt}`,onSwitch:`?${xt}`,range:`?${gt}`,onRange:`?${xt}`,onChange:`?${xt}`},Et={id:yt,container:kt,url:yt,poster:yt,type:yt,theme:yt,lang:yt,volume:bt,isLive:vt,muted:vt,autoplay:vt,autoSize:vt,autoMini:vt,loop:vt,flip:vt,playbackRate:vt,aspectRatio:vt,screenshot:vt,setting:vt,hotkey:vt,pip:vt,mutex:vt,backdrop:vt,fullscreen:vt,fullscreenWeb:vt,subtitleOffset:vt,miniProgressBar:vt,useSSR:vt,playsInline:vt,lock:vt,gesture:vt,fastForward:vt,autoPlayback:vt,autoOrientation:vt,airplay:vt,proxy:`?${xt}`,plugins:[xt],layers:[$t],contextmenu:[$t],settings:[$t],controls:[{...$t,position:(t,e,r)=>{const n=["top","left","right"];return X("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${vt}`,html:yt,url:yt}],highlight:[{time:bt,text:yt}],thumbnails:{url:yt,number:bt,column:bt,width:bt,height:bt,scale:bt},subtitle:{url:yt,name:yt,type:yt,style:wt,escape:vt,encoding:yt,onVttLoad:xt},moreVideoAttr:wt,i18n:wt,icons:wt,cssVar:wt,customType:wt},Tt=new WeakSet;class Ct{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return N(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?O(e,r):I(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(w(this.art))return;const e="function"===typeof t?t(this.art):t;if(w(this.art))return;if(e.html=e.html||"",o(e,$t),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;X(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=$(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,r);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){O(t,`art-${r}`),O(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):_(e,t),i.html&&_(t,i.html),i.style&&j(t,i.style),i.tooltip&&Y(t,i.tooltip)}(i,this.$parent,this.name,r,this.id,e),a.closed)return;if(e.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,r,i),c=!0,n.set(r,{$ref:i,events:s,option:e}),e.mounted&&e.mounted.call(this.art,i),i}catch(d){try{T(i)}catch(p){console.warn("ArtPlayer component cleanup failed:",p)}throw n.get(r)?.$ref===i&&n.delete(r),c&&this[r]===i&&(l?Object.defineProperty(this,r,l):delete this[r]),i.remove(),d}}remove(t){X(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Tt.has(e)){Tt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{T(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Tt.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Lt extends Ct{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,$(t,this.$parent),p||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=L(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return{...t,html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=L(e,t),n=R('[data-value="1"]',t);n&&D(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&D(r,"art-current")})}}}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return{...t,html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=L(e,t),n=R('[data-value="default"]',t);n&&D(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&D(r,"art-current")})}}}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(Q(t))}`).join("");return{...t,html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=L(e,t),n=R('[data-value="normal"]',t);n&&D(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&D(r,"art-current")})}}}}({name:"flip",index:30})),this.add(function(t){return e=>({...t,html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return{...t,html:`ArtPlayer ${i}`}}({name:"version",index:50})),this.add(function(t){return e=>({...t,html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=z(e),{height:c,width:d}=z(r);let p=n-s,u=o-l;n+d>s+a&&(p=a-d),o+c>l+i&&(u=i-c),j(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{P(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function St(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{s?.removeEventListener("abort",l)}}),s?.addEventListener("abort",l,{once:!0}),l}function Pt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Mt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const zt=new WeakMap,At=new WeakMap,Rt=new WeakMap;function Ot(t){return Rt.get(t)||b(t)}function It(t){const e=zt.get(t),r=Rt.get(t);return()=>zt.get(t)===e&&(!e||e.active())&&Rt.get(t)===r&&(!r||!r.closed)}function Nt(t){const e=Rt.get(t),r=b(t).child(),n=r.child();Rt.set(t,r),r.add(()=>{Rt.get(t)===r&&Rt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!w(t)&&!n.closed&&zt.get(t)===o};return zt.set(t,o),n.add(()=>{zt.get(t)===o&&zt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function _t(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function Wt(t,e,r){At.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{At.get(t)===e&&(At.delete(t),_t(e))}}function Dt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Ft(t,e){const{$progress:r}=t.template,{left:n}=z(r),o=J((p?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:tt(i),width:o,percentage:J(o/r.clientWidth,0,1)}}function Vt(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Ft(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Yt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=E(e),{on:a}=L(t,e);let s=()=>{};const l=mt(".art-progress-hover",e),c=mt(".art-progress-loaded",e),d=mt(".art-progress-played",e),u=mt(".art-progress-highlight",e),h=mt(".art-progress-indicator",e),f=mt(".art-progress-tip",e);function m(r,n){const{width:o,time:i}=n||Ft(t,r);f.textContent=i||"00:00";const a=f.clientWidth;o<=a/2?H(f,"left",0):o>e.clientWidth-a/2?H(f,"left",e.clientWidth-a+"px"):H(f,"left",o-a/2+"px")}r.indicator?_(h,r.indicator):H(h,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const g="played"===r&&a&&p;if("loaded"===r&&H(c,"width",100*n+"%"),"hover"===r&&(H(l,"width",100*n+"%"),P(a,u)?function(r){const{width:n}=Ft(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;f.textContent=o??"";const i=f.clientWidth;n<=i/2?H(f,"left",0):n>e.clientWidth-i/2?H(f,"left",e.clientWidth-i+"px"):H(f,"left",n-i/2+"px")}(a):m(a),0===n?I(o,"art-progress-hover"):O(o,"art-progress-hover")),"played"===r&&(H(d,"width",100*n+"%"),H(h,"left",100*n+"%")),g){O(o,"art-progress-hover");m(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=Pt(i,()=>{I(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function Bt(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Yt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=L(t,e),a=E(e);let s=0;const l=()=>{const e=It(t);return()=>!a.closed&&!w(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!p){let e;i(r,"click",e=>{e.target!==n&&Vt(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=Ft(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(n?.()){const{second:o,percentage:i}=Ft(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t)}})}function Ht(t){const{option:e}=t.art;e.isLive||t.add(Bt({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e,a=ft(t,o.play),s=ft(t,o.pause);function l(){H(a,"display","flex"),H(s,"display","none")}function c(){H(a,"display","none"),H(s,"display","flex")}Y(a,i.get("Play")),Y(s,i.get("Pause")),n(a,"click",()=>{G(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o}=e,i=ft(t,o.volume),a=ft(t,o.volumeClose),s=ft(t,'
'),l=ft(s,'
'),c=ft(l,'
'),d=ft(l,'
'),u=ft(d,'
'),h=ft(u,'
'),f=ft(d,'
');function m(t){const{top:e,height:r}=z(d);return 1-(t.clientY-e)/r}function g(){if(e.muted||0===e.volume)H(i,"display","none"),H(a,"display","flex"),H(f,"top","100%"),H(h,"top","100%"),c.textContent="0";else{const t=100*e.volume;H(i,"display","flex"),H(a,"display","none"),H(f,"top",100-t+"%"),H(h,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(g(),r("video:volumechange",g),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),p)H(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=m(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=m(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>({...t,style:p?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=L(e,t);function n(){const r=`${tt(e.currentTime)} / ${tt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!b(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!p&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=L(e,t),{icons:n}=e;ft(t,n.screenshot),r(t,"click",()=>{G(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e;ft(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{Y(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e;ft(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{Y(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=L(e,t),{icons:n}=e;ft(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenWebOn),s=ft(t,o.fullscreenWebOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(Y(t,i.get("Exit Web Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(Y(t,i.get("Web Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=L(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenOn),s=ft(t,o.fullscreenOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(Y(t,i.get("Exit Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(Y(t,i.get("Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rqt.get(t).option.selector}),it(t,"$control_item",{get:()=>qt.get(t).item}),it(t,"$control_value",{get:()=>qt.get(t).value})),qt.set(t,e)}function Xt(t,e){t.innerHTML=e}function Gt(t,e,r,n,o){const{proxy:i}=t.events,a=E(n),s=r.selector;O(n,"art-control-selector");const l=document.createElement("div");O(l,"art-selector-value"),_(l,r.html),n.textContent="",_(n,l);const c=ft(n,'
');for(let u=0;u{if(a.closed)return;const o=S(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++d,c=()=>!a.closed&&s===d,p=a.add(function(t,e){return jt.set(t,e),()=>{jt.get(t)===e&&jt.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,i,i.$control_item,n);c()&&Xt(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Kt extends Ct{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;$(t,n);const{on:o}=L(t,n);o("mousemove",()=>{p||(this.show=!0)}),o("click",()=>{p?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=P(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(I(r,"art-hide-cursor"),O(r,"art-hover"),this.timer=Date.now()):(O(r,"art-hide-cursor"),I(r,"art-hover"))}),this.init(),b(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=E(e),{on:i}=L(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){Ht(this)}add(t){if(w(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:X(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Xt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Zt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(w(t))return;const n=P(r,e);t.isInput=n&&"INPUT"===r.target?.tagName,t.isFocus=n,t.emit(n?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),b(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(w(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),w(t))return;(!p||!t.isLock&&i)&&G(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),w(t))return;p?!t.isLock&&s&&G(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function Jt(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!w(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),b(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(w(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:It(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Vt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=J((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),p=J(i.time+t.duration*d*l,0,t.duration);t.seek=p,n(i)&&(t.emit("setBar","played",J(p/t.duration,0,1),o),n(i)&&(t.notice.show=`${tt(p)} / ${tt(t.duration)}`))},cancel:r}}const Qt=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],te=["resize","scroll","orientationchange"];const ee=new WeakMap;function re(t){const e=ee.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function ne(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=ne(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=re(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(o?.capture),once:Boolean(o?.once),passive:o?.passive,signal:o?.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||c?.aborted)return()=>{};let d=!0;function p(r=!1){(d||r)&&(e.removeEventListener(i,n,l),c?.removeEventListener("abort",u),d=!1,t.destroyEvents.delete(u))}function u(){p()}t.destroyEvents.add(u);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?p(!0):c?.aborted?u():c?.addEventListener("abort",u,{once:!0})}catch(h){try{p(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return u}function oe(t){return(e,r)=>{if(w(t))return;const n=(...e)=>{if(!w(t))return r(...e)};t.on(e,n),b(t).add(()=>{t.off(e,n)})}}function ie(t){if(!t.constructor.USE_RAF)return;const e=b(t);let r=()=>{};const n=()=>{w(t)||(t.playing&&t.emit("raf"),w(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),oe(t)("destroy",()=>r())}class ae{constructor(t){this.destroyEvents=new Set,function(t,e){ee.set(t,{scope:b(e),cleaning:!1})}(this,t),b(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Zt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{w(t)||(O(r,"art-hover"),t.emit("hover",!0,e))},e=>{w(t)||(I(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{w(t)||t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t,o=oe(t);o("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),w(t)||(t.aspectRatio=e,w(t)||(n.show=""))});const i=b(t);let a=()=>{};const s=()=>{w(t)||(a(),a=Pt(i,()=>t.emit("resize"),n.RESIZE_TIME))};o("window:orientationchange",s),o("window:resize",s);const l=t.template.$player.ownerDocument.defaultView?.screen?.orientation;"function"===typeof l?.addEventListener&&e.proxy(l,"change",s)}(t,this),function(t,e){if(!p||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=Jt(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=b(t),a=oe(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=o?.innerHeight||n.documentElement.clientHeight,a=o?.innerWidth||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),w(t)||(s=!0,Pt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;b(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){if(w(t))return;const a=++n,s={disposers:[]},l=()=>a!==n||w(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,a=i.window||n.ownerDocument?.defaultView||window,c=(n,o,i)=>{for(const a of o){if(l())return;s.disposers.push(e.proxy(n,a,e=>{r!==s||w(t)||t.emit(`${i}:${a}`,e)}))}};c(o,Qt,"document"),c(a,te,"window")}catch(d){throw o(s),d}if(l())return void o(s);const c=r;r=s,o(c)}i(),e.bindGlobalEvents=i}(t,this),ie(t)}proxy(t,e,r,n={}){return Array.isArray(e),ne(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=re(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function se(t){if(t&&1===t.nodeType)return t}function le(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const ce=new WeakMap;class de{constructor(t){this.art=t,this.keys={},ce.set(this,{subscribed:!1}),p||this.init()}init(){const t=this.art;if(w(t))return;const e=ce.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{G(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!w(t)){if(t.isFocus&&function(t,e){if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const r=function(t,e){const r=t.target;return 9===r?.nodeType?r:r?.ownerDocument||t.view?.document||e}(t,e);let n=se(r.activeElement);for(;n?.shadowRoot?.activeElement;)n=se(n.shadowRoot.activeElement);if(n&&le(n))return!1;const o=se(t.composedPath?.()[0])||se(t.target);return!o||!le(o)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const pe={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",pe);class ue{constructor(t){this.art=t,this.languages={"zh-cn":pe},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=st(this.languages,t)&&this.languages[t]||{}}get(t){return st(this.language,t)&&this.language[t]||t}update(t){this.languages=ct(this.languages,t),this.init()}}const he={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class fe{constructor(t){const e={...he,...t.option.icons};for(const r in e)it(this,r,{get:()=>B(r,e[r])})}}const me=new WeakMap;class ge extends Ct{constructor(t){super(t),this.name="info",me.set(this,{revision:0}),p||this.init()}init(){const t=me.get(this),e=++t.revision;if(t.scope?.dispose(),w(this.art)||t.revision!==e)return;const r=b(this.art).child();t.scope=r,r.add(()=>{t.scope===r&&(t.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!w(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const p=Array.from(s.querySelectorAll("[data-video]")),u=()=>e.dispose();t.on("destroy",u),e.add(()=>{t.off("destroy",u)});const h=()=>{try{for(const t of p){if(!n())return;const e=Reflect.get(c,t.dataset.video??"undefined");if(!n())return;const r="number"===typeof e?e.toFixed(2):e;if(!n())return;if(t.textContent!==r){const e=null==r?null:`${r}`;if(!n())return;t.textContent=e}}n()&&Pt(e,h,a.INFO_LOOP_TIME)}catch(t){o(t)}};n()&&h()}catch(i){o(i)}}(this.art,r,()=>{this.show=!1})}}class ve extends Ct{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{H(i,"display","none"),H(s,"display",null),w(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,y(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),w(t)||n.proxy(e.$state,"click",()=>{w(t)||G(t.play())})}}const we=new WeakMap;function xe(t){const e=we.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class ke{constructor(t){this.art=t,this.timer=null,we.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),b(t).add(()=>{t.off("destroy",e)}),b(t).add(()=>{this.destroy()})}destroy(){xe(this)}set show(t){if(w(this.art))return;const e=we.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){xe(this);const i=e.revision,a=()=>!w(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(O(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(w(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",w(this.art)||e.revision!==t||I(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else I(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function $e(t,e){return function(t,e){const r=ct(e,t);return r.container=t.container,o(r,Et)}(t,e)}function Ee({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Te(t,e){if(!Ee(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Ee(r)?r:void 0}const Ce=new WeakMap;function Le(t){return Ce.get(t)||0}function Se(t,e,r,n=!1){const o=e=>{w(t)||r(e)};t[n?"once":"on"](e,o),b(t).add(()=>{t.off(e,o)})}function Pe(t,e,r){for(const[n,o]of e){if(w(t)||r&&!r())return;t[n].show=o}}function Me(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=Ot(t),l=0;return{reset(){l=0,a?.dispose(),I(i,"art-error")},loadStart(){I(i,"art-error")},schedule(c){(async c=>{if(w(t))return;const d=Ot(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const p=d.child();a=p,p.add(()=>{a===p&&(a=void 0)});const u=()=>!w(t)&&!p.closed&&d===Ot(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}const ze=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],Ae=(()=>{if("undefined"===typeof document)return!1;const t=ze[0],e={};for(const r of ze){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Re={change:Ae.fullscreenchange,error:Ae.fullscreenerror},Oe={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Oe.off("change",o),r()};Oe.on("change",o);const i=t[Ae.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Oe.isFullscreen)return void t();const r=()=>{Oe.off("change",r),t()};Oe.on("change",r);const n=document[Ae.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Oe.isFullscreen?Oe.exit():Oe.request(t,e),onchange(t){Oe.on("change",t)},onerror(t){Oe.on("error",t)},on(t,e){const r=Re[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Re[t];r&&document.removeEventListener(r,e,!1)},raw:Ae};function Ie(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(Oe,{isFullscreen:{get:()=>Boolean(document[Ae.fullscreenElement])},element:{enumerable:!0,get:()=>document[Ae.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Ae.fullscreenEnabled])}});const Ne=new WeakMap;function _e(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function We(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ne.get(t);if(!n){n=new WeakMap,Ne.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),_e(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),_e(i))}function De(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,p=!1,u=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!p&&r&&We(t))});const m=()=>{d&&!p&&(r?t.element===t.target:o())&&f()};if(St(i,t.document,t.changeEvent,m),St(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(u=!0,d&&!p&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){Ne.get(t.document)?.delete(t.target)}(t);const e=r?t.request():t.exit();p=Boolean(e&&"function"===typeof e.then),d=!0,c&&!p&&r&&We(t),p?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):u?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Fe(t,e){const r=b(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,p=!1,u=!1;function h(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),h()}),St(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return Ne.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void h();if(r===s||w(t))return;s=r;const o=l,a=()=>w(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),St(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(u||void 0!==a||i()))&&!w(t)&&t.emit("fullscreenError",r)}),{get:()=>!w(t)&&i(),set(n){if(w(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?p=!1:d&&(p=!0),a?.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();u=!0,d=c;const s=De(e,r,c,()=>{!w(t)&&c||h()},()=>!i());u=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw w(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const Ve=new WeakSet;function Ye(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Be(t){Ve.delete(t),t.removeEventListener("webkitbeginfullscreen",He),t.removeEventListener("webkitpresentationmodechanged",He)}function He(t){if(Ve.has(this)&&Ye(this,"webkitbeginfullscreen"===t.type)){Be(this);try{this.webkitExitFullscreen?.()}catch{}}}function je(t){Ve.add(t),t.addEventListener("webkitbeginfullscreen",He),t.addEventListener("webkitpresentationmodechanged",He)}function qe(t){const{$video:e}=t.template,r=b(t).child();let n=!1,o=Ye(e),i=o,a=!1,s=0;const l=()=>Ye(e,n);function c(r){if(w(t)||(c=e,Ve.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const p=s,u=()=>w(t)||l()!==d||p!==s&&i!==d;t.emit("fullscreen",d),u()||(d&&(t.state="fullscreen"),u()||t.emit("resize"))}r.add(()=>{s++,i=!1,a&&je(e),l()&&e.webkitExitFullscreen?.()}),St(r,e,"webkitbeginfullscreen",()=>c(!0)),St(r,e,"webkitendfullscreen",()=>c(!1)),St(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!w(t)&&l(),set(r){if(w(t))return;const n=++s;if(i=Boolean(r),r){if(Be(e),t.state="fullscreen",w(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,je(e)),l()&&e.webkitExitFullscreen()}}}function Ue(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Xe({node:t,parent:e,next:r}){if(!e)return void t.parentNode?.removeChild(t);const n=r?.parentNode===e?r:null;t.parentNode===e&&t.nextSibling===n||e.insertBefore(t,n)}function Ge(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function Ke(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Ze(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),St(o,e,"click",n),St(o,l,"click",()=>{G(t.play())}),St(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const p=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};St(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=Ge(i.left,i.top,Ke(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:p,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function Je(t){const{$player:e,$video:r}=t.template,n=b(t).child();let o,i,a=0,s=!1,l=!1;const c=()=>!w(t)&&e.classList.contains("art-mini");function d(){if(i){const e=i,r=a;i=void 0;try{Xe(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(w(t))return;const r=++a;l=!1,d(),w(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function u(){if(w(t))return;const h=++a;if(s)l=!0;else if(t.state="mini",!w(t)&&h===a){i??(i=Ue(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Ze(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void u();if(!o||w(t))return;if(h!==a)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),w(t)||h!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:{...Ge(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,Ke(o.element));if(w(t)||h!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),w(t)||h!==a)return;t.storage.set("left",i.left)}w(t)||h!==a||t.emit("mini",!0)}catch(f){const r=l;throw l=!1,w(t)||h!==a&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),f}}}return n.add(()=>{a++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?u():p()}}}const Qe=new WeakSet,tr=t=>"picture-in-picture"===t.webkitPresentationMode;function er(t){Qe.delete(t),t.removeEventListener("webkitpresentationmodechanged",rr),t.removeEventListener("enterpictureinpicture",rr)}function rr(){if(Qe.has(this)&&tr(this)){er(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function nr(t){Qe.add(t),t.addEventListener("webkitpresentationmodechanged",rr),t.addEventListener("enterpictureinpicture",rr)}function or(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function ir(t,e,r){return new Promise((n,o)=>{if(w(t)||e===t.url)return void n();const i=Nt(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),d=t=>l(!0,t);i.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child();let u=!1,h=!1,f=!1;const m=function(t,e,r){let n,o=!1,i=!1,a=!1,s=Le(t);const l=()=>a||Le(t)!==s,c=()=>!!t.template?.$video?.seeking;return{restore(){if(!r()||l())return;const i=Le(t);t.currentTime=e,s=Le(t),s>i+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}(t,r,c),g=async()=>{if(t.aspectRatio=o,c()){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}},v=()=>{if(c()&&!h&&u)try{if(t.template?.$video?.seeking)return;if(!c())return;if(f||(f=!0,t.playbackRate=s),!m.ready()||!c()||h)return;h=!0,p.dispose(),g().catch(d)}catch(e){d(e)}},y={"video:error":d,"video:loadedmetadata":()=>{if(c())try{m.restore()}catch(t){d(t)}},"video:canplay":()=>{u=!0,v()},"video:seeked":v,seek:m.manual},b=a.child(),w=[],x=Object.keys(y);for(const e of x)or(b,t,e,t=>{i.acceptingEvents&&w.push([e,t])},!1);if(Wt(t,i,e),!c())return;if(t.notice.show="",!c())return;const k=()=>{if(b.dispose(),!e)return void l();const r={};for(const e of x)r[e]=or(p,t,e,y[e],"video:seeked"!==e);for(const[t,e]of w){if(!c()||p.closed)break;r[t](e)}w.length=0};i.assigned?k():i.onAssigned=k}catch(p){d(p)}})}function ar(t,e){const{number:r,column:n,width:o,height:i,scale:a}=t,{imageWidth:s,videoWidth:l,videoHeight:c,progressWidth:d,position:p}=e,u=Number(n),h=Number(o)*Number(a)||s/u,f=Number(i)*Number(a)||h/(l/c),m=Math.floor(p/(d/Number(r)));return{height:`${f}px`,width:`${h}px`,backgroundPosition:`-${m%u*h}px -${Math.floor(m/u)*f}px`,left:p<=h/2?0:p>d-h/2?d-h+"px":p-h/2+"px"}}function sr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(w(t))return;const o=function(t){const e=At.get(t);return At.delete(t),e||Nt(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await Mt(o.scope)&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||K(n),s=e.customType[a];if(a&&s){if(!(await Mt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;or(l,t,"video:canplay",()=>{c=!d}),or(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Dt(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||or(o.scope,t,"video:canplay",e)}}catch(i){Dt(o,i)}finally{_t(o)}}})}const lr=[function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){const n=e;if(void 0===r)return n[t];n[t]=r}})},function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=It(t),s=await i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})},function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${tt(t.currentTime)} / ${tt(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;it(t,"forward",{set(e){r.seek=t.currentTime+e}}),it(t,"backward",{set(e){r.seek=t.currentTime-e}})},function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=J(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),it(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})},function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){Ce.set(t,Le(t)+1)}(t),e.currentTime=J(n,0,t.duration))}})},function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})},function(t){const e=e=>ir(t,e,0);it(t,"switchQuality",{value:e=>ir(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})},function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;it(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!w(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Te({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(w(t))return;"width"===r?.axis?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,w(t)||t.emit("aspectRatio",i)}}})},function(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=It(t);return new Promise((a,s)=>{const l=r=>{try{!w(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}it(t,"getDataURL",{value:()=>o(!1)}),it(t,"getBlobUrl",{value:()=>o(!0)}),it(t,"screenshot",{value:async e=>{const n=It(t),o=await t.getDataURL();if(!w(t)&&n()){const i=e||`artplayer_${tt(r.currentTime)}`;!w(t)&&n()&&Z(o,`${i}.png`),!w(t)&&n()&&t.emit("screenshot",o)}return o}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(w(t))return;const i=function(t){const e=Oe.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>Ie(t,e.requestFullscreen,void 0),exit:()=>Ie(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",Fe(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",qe(t)):it(t,"fullscreen",{get:()=>!1,set(){w(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",lt(t,"fullscreen"))};t.once("video:loadedmetadata",i),b(t).add(()=>{t.off("video:loadedmetadata",i)})},function(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(Xe(t.placement),r()))}return b(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(i){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(a){throw new f([i,a])}throw i}}),i=>{if(w(t))return;const a=++n,s=()=>a===n&&!w(t);if(i){r||(r={placement:Ue(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);it(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})},function(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?it(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=b(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function p(e,r,n){e.then(()=>{!r||!w(t)&&a||d()},e=>{w(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),St(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!w(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),St(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!w(t)&&o()?e:null,set(n){if(w(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",w(t)||c!==i)return;s=!0;try{p(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&p(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=b(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(w(t)||Qe.has(e))return;const s=tr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),w(t)||i!==l||tr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&nr(e),tr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])St(r,e,l,()=>s());return{get:()=>!w(t)&&tr(e),set(r){if(w(t))return;const n=++i,l=a;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(er(e),t.state="pip",w(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===i&&(o=!1),c}}else o&&(o=!1,nr(e)),tr(e)&&e.webkitSetPresentationMode("inline");w(t)||n!==i||l!==a||tr(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){w(t)||(r.show=e.get("PIP Not Supported"))}})},function(t){const{$video:e}=t.template,r=t;it(t,"loaded",{get:()=>r.loadedTime/e.duration}),it(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})},function(t){it(t,"played",{get:()=>t.currentTime/t.duration})},function(t){const{$video:e}=t.template;it(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})},function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(w(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Ee(o))return;const i=z(e),a=Te(i,o.width/o.height);a&&!w(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})},function(t){const e=t;it(t,"rect",{get:()=>z(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}it(t,"x",{get:()=>e.left+window.pageXOffset}),it(t,"y",{get:()=>e.top+window.pageYOffset})},function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){w(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,w(t)||t.emit("flip",o))}})},function(t){it(t,"mini",Je(t))},function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){H(e,"backgroundImage",`url(${t})`)}})},function(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(w(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Ee(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||w(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})},function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})},function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})},function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})},function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];it(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;nn.$track?.offset||0,set(o){const{cues:i}=t.subtitle;if(!n.$track||0===i.length)return;const a=J(o,-10,10);n.$track.offset=a;for(let e=0;e{if(!w(t))switch(e.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,w(t)||it(t,"airplay",{value(){if(!w(t))if(i){const e=o.webkitShowPlaybackTargetPicker;if(w(t))return;Reflect.apply(e,o,[]),w(t)||t.emit("airplay")}else{const n=e.get("AirPlay Not Available");w(t)||(r.show=n)}}}))},function(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:i?.html||"",selector:e,async onSelect(e,r,i){const a=function(t){return t&&jt.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!w(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!w(t)&&a()&&(n.show=r)}return e.html}})}})},function(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,s=b(t).child(),l=!1;function c(){const e=s;s=b(t).child(),o=void 0,l=!1,a=void 0,e.dispose()}function d(){const i=a,l=s;if(!i||!o)return;const c=()=>!w(t)&&!l.closed&&s===l&&a===i&&i.sourceActive()&&t.controls?.thumbnails===i.element;if(!c())return;const d=r.clientWidth*i.percentage;if(!(d>0&&d{const h=t.controls?.thumbnails,{url:f,scale:m}=e.thumbnails;if(!w(t)&&h&&f&&("hover"===r||"played"===r&&u&&p)){if(i!==h){const t=E(h);if(t.closed)return;i=h,t.add(()=>{i===h&&(i=void 0,c())})}if(a={percentage:n,element:h,sourceActive:It(t)},o)d();else if(!l){const t=s;l=!0,function(t,e,r){return q(t,e,r)}(f,m,t).then(e=>{s!==t||t.closed||(l=!1,o=e,d())}).catch(e=>{s!==t||t.closed||(l=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{w(t)||!e.url||t.option.isLive||w(t)||(t.option.thumbnails=e,c())}})},function(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{w(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Me(t);!function(t,e){Se(t,"video:canplay",()=>{e.reset(),Pe(t,[["loading",!1]])}),Se(t,"video:canplay",()=>{Pe(t,[["loading",!1],["controls",!0],["mask",!0]]),w(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Se(t,"video:ended",()=>{if(e.loop){const e=It(t);if(t.seek=0,w(t)||!e())return;G(t.play()),e()&&Pe(t,[["controls",!1],["mask",!1]],e)}else Pe(t,[["controls",!0],["mask",!0]])})}(t),Se(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Se(t,"video:loadedmetadata",()=>{t.emit("resize"),p&&Pe(t,[["loading",!1],["controls",!0],["mask",!0]])}),Se(t,"video:loadstart",()=>{e.loadStart(),Pe(t,[["loading",!0],["mask",!1],["controls",!0]])}),Se(t,"video:pause",()=>{Pe(t,[["controls",!0],["mask",!0]])}),Se(t,"video:play",()=>{Pe(t,[["mask",!1]]),w(t)||H(r,"display","none")}),Se(t,"video:playing",()=>Pe(t,[["mask",!1]])),Se(t,"video:progress",()=>{t.playing&&Pe(t,[["loading",!1]])}),Se(t,"video:seeked",()=>Pe(t,[["loading",!1],["mask",!0]])),Se(t,"video:seeking",()=>Pe(t,[["loading",!0],["mask",!1]])),Se(t,"video:timeupdate",()=>Pe(t,[["mask",!1]])),Se(t,"video:waiting",()=>Pe(t,[["loading",!0],["mask",!1]]))}(t,e)},function(t){if(w(t))return;const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const s in e.moreVideoAttr){if(w(t))return;const r=e.moreVideoAttr[s];if(w(t))return;t.attr(s,r)}if(w(t))return;if(e.muted){const r=e.muted;if(w(t))return;t.muted=r}if(w(t))return;if(e.volume){const r=J(e.volume,0,1);if(w(t))return;n.volume=r}if(w(t))return;const i=r.get("volume");if(w(t))return;if("number"===typeof i&&(n.volume=J(i,0,1)),w(t))return;if(e.poster){const r=`url(${e.poster})`;if(w(t))return;H(o,"backgroundImage",r)}if(w(t))return;if(e.autoplay){const r=e.autoplay;if(w(t))return;n.autoplay=r}if(w(t))return;if(e.playsInline){if(w(t))return;if(n.playsInline=!0,w(t))return;n["webkit-playsinline"]=!0}if(w(t))return;if(e.theme){const r=e.cssVar,n=e.theme;if(w(t))return;r["--art-theme"]=n}for(const s in e.cssVar){if(w(t))return;const r=e.cssVar[s];if(w(t))return;t.cssVar(s,r)}if(w(t))return;const a=e.url;w(t)||(t.url=a)}];class cr{constructor(t){if(!w(t)){sr(t);for(const e of lr){if(w(t))return;e(t)}}}}const dr=new WeakMap,pr="art-auto-orientation-fullscreen";function ur(t){if(dr.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const hr="art-auto-orientation",fr=["width","height","transform-origin","transform"];function mr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Ee(t)&&Ee(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=b(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(hr);r.classList.remove(hr),n&&(t.isRotate=!1,w(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=A();if(w(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=fr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(hr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{w(t)||(r?o?s(!1):e()&&(i(),i=Pt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(pr),t&&(t.cancelled=!0,ur(t),t.settled&&dr.get(t.orientation)===t&&dr.delete(t.orientation))}return b(t).add(o),i=>{if(w(t))return;if(!i)return void o();if(n&&!n.cancelled&&dr.get(n.orientation)===n)return;const a=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof a?.lock||"function"!==typeof a.unlock||!e())return;const s={orientation:a,cancelled:!1,settled:!1};n=s,dr.set(a,s);const l=()=>!w(t)&&!s.cancelled&&n===s&&dr.get(a)===s,c=e=>{s.settled=!0;const o=l();dr.get(a)===s&&dr.delete(a),n===s&&(n=void 0),o&&(r.classList.remove(pr),t.notice.show=e)};try{const t=a.lock(a.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,l()?r.classList.add(pr):(ur(s),dr.get(a)===s&&dr.delete(a))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),b(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function gr(t){return t.get("times")||{}}function vr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||w(t))return()=>{};const s=mt(".art-auto-playback-last",a),l=mt(".art-auto-playback-jump",a),c=mt(".art-auto-playback-close",a);ft(c,r.close);const d=E(a);let p,u=0;const h=()=>{const r=++u;if(p?.dispose(),d.closed||w(t)||u!==r)return;const h=d.child();p=h;const f=()=>p===h&&!h.closed&&!w(t);h.add(()=>{p===h&&(p=void 0,H(a,"display","none"))});const m=Ot(t).add(()=>{h.dispose()});h.add(()=>{m()});const g=gr(n)[t.option.id||t.option.url];if(!f())return;if(H(a,"display","none"),!f()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!f())return;if(H(a,"display","flex"),!f())return;const v=`${e.get("Last Seen")} ${tt(g)}`;if(!f())return;if(s.textContent=v,!f())return;const y=e.get("Jump Play");if(!f())return;if(l.textContent=y,!f())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{f()&&r()});h.add(()=>{t.events.remove(n)})};if(b(c,()=>{H(a,"display","none")}),!f())return;if(b(l,()=>{t.seek=g,f()&&(G(t.play()),f()&&(H(i,"display","none"),f()&&H(a,"display","none")))}),!f())return;let x=()=>{},k=!1;const $=()=>{!k&&f()&&(k=!0,x(),Pt(h,()=>{f()&&H(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",$),x=h.add(()=>{t.off("video:timeupdate",$)}),k&&x()};return()=>{C(t,a,"ready",h),C(t,a,"restart",h)}}(t);return function(t){const{storage:e,constructor:r}=t;oe(t)("video:timeupdate",()=>{if(!t.playing)return;const n=gr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;w(t)||(o.length>i&&delete n[o[0]],n[a]=s,w(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return gr(e)},clear:()=>e.del("times"),delete(t){const r=gr(e);return delete r[t],e.set("times",r),r}}}function yr(t){let e,r=0;return{start:n=>{const o=++r;if(e?.scope.dispose(),o!==r||w(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:Ot(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{e?.active||I(t.template.$player,"art-fast-forward")}}),Pt(i.scope,()=>{if(e!==i||w(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||w(t))return;t.playbackRate=r,e!==i||i.scope.closed||w(t)||O(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,e?.scope.dispose()}}}function br(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=yr(t),i=oe(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return N(r,"art-fast-forward")}}}function wr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return N(n,"art-lock")}function i(){w(t)||(O(n,"art-lock"),w(t)||(t.isLock=!0,w(t)||t.emit("lock",!0)))}function a(){w(t)||(I(n,"art-lock"),w(t)||(t.isLock=!1,w(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=E(e);if(n.closed||w(t))return;const o=ft(e,r.lock);if(n.closed||w(t))return;const i=ft(e,r.unlock);n.closed||w(t)||(H(o,"display","none"),C(t,e,"lock",e=>{w(t)||(H(o,"display",e?"inline-flex":"none"),n.closed||w(t)||H(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function xr(t){return oe(t)("control",e=>{e?I(t.template.$player,"art-mini-progress-bar"):O(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class kr{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){w(t.art)||!e.miniProgressBar||e.isLive||t.add(xr),!w(t.art)&&e.lock&&p&&t.add(wr),w(t.art)||!e.autoPlayback||e.isLive||t.add(vr),!w(t.art)&&e.autoOrientation&&p&&t.add(mr),!w(t.art)&&e.fastForward&&p&&!e.isLive&&t.add(br)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!w(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(w(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(w(t.art))return t;let o=n;const i=st(t,o);if(w(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return w(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),w(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const $r=new WeakMap;function Er(t){return!t.closed&&!$r.get(t)}function Tr(t){$r.set(t,($r.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=($r.get(t)||1)-1;r?$r.set(t,r):$r.delete(t)}}const Cr=new WeakMap,Lr=new WeakMap,Sr=["$parent","$parents","$option","$events","$formatted"];function Pr(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=Cr.get(r);if(!t||!t.owner.active||t.owner.scope?.closed||!t.option.includes(r))return!1;if(!t.parent)return t.owner.root===t.option;if(Cr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function Mr(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function zr(t){const e=Cr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Ar(t,e){for(let r=0;r{c&&c!==r&&c.dispose()},()=>Dr(t,o)])try{e()}catch(d){d instanceof f?l.push(...d.errors):l.push(d)}if(r.closed||w(t)||(o.push(...i.splice(0)),Wr.set(r,o),Nr.set(e,r),_r.set(e,n)),a(),l.length)throw new f(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function Hr(t,e,r,n,o,i){const a=i||Vr(e);if(!Er(a)||w(t))return;const s=t.proxy(r,n,e=>{if(Er(a)&&!w(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Er(a)||w(t)?t.events.remove(s):(zr(e).events.push(s),i&&i!==Nr.get(e)&&i.add(()=>{const r=zr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function jr(t,e,r,n){const o=Vr(e);if(!Er(o)||w(t))return;const i=(...e)=>{if(Er(o)&&!w(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function qr(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:i},template:{$player:a,$setting:s,$bottom:l}}=e;if(!n.setting||!t.show||!r)return;const c=a.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),u=c.width/a.offsetWidth||1,h=(d.left-c.left+d.width/2)/u-a.clientLeft,f=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:a.clientWidth,containerHeight:a.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:i,controlCenter:h,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${f.height}px`,s.style.width=`${f.width}px`,e.isRotate||p||(h+f.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${f.left}px`,s.style.right="auto"))}const Ur=new WeakMap;function Xr(t){Ur.delete(t)}const Gr=new WeakMap;function Kr(t,e){e?Gr.set(t,e):Gr.delete(t)}function Zr(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=Gr.get(t),o=n?.();for(const i of["html","icon","tooltip"]){const t=e.get(i)?.value;t instanceof Node&&r.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{for(const r of Reflect.ownKeys(t))!e.has(r)&&Object.getOwnPropertyDescriptor(t,r)?.configurable&&Reflect.deleteProperty(t,r);for(const[r,n]of e)Object.defineProperty(t,r,n);o?.(),Kr(t,n);for(const{node:t,parent:e,next:n}of r)e?e.insertBefore(t,n?.parentNode===e?n:null):t.parentNode?.removeChild(t)}}const Jr=new WeakMap;async function Qr(t,e,r,n,o,i,a,s){try{const l=Vr(e),c=Vr(i),d=(Jr.get(i)||0)+1;Jr.set(i,d);const p=()=>Er(l)&&Er(c)&&!w(t.art)&&Jr.get(i)===d;if(s?.(),!p())return;const u=await o.call(t.art,e,r,n);p()&&Reflect.set(i,a,u)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}}function tn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const en=new WeakMap;function rn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof f?e.push(...r.errors):e.push(r)}if(e.length)throw new f(e)}function nn(t){en.get(t)?.()}function on(t,e){const r=t.find(e.name);if(w(t.art))return r||e;if(!r)return t.add(e);Xr(r),nn(r);const n=Zr(r),o=r.$item,i=o?.parentNode,a=o?.nextSibling,s=o?tn(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=Br(t.art,e);r&&i.push(r)}for(const t of n)a.push(Tr(Or(t)))}catch(l){try{rn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,rn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,rn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Ir(t)),...a]))}}}(t,r);let p=!0,u=!1;const h=()=>{if(!p)return;p=!1;for(const t of d.items)en.get(t)===h&&en.delete(t);if(w(t.art))return void d.dispose();const e=r.$item;try{rn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{i&&o&&i.insertBefore(o,a?.parentNode===i?a:null)},()=>t.format(),()=>{if(u){t.active=l,l&&t.cache.has(l)&&D(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(f){console.warn("ArtPlayer setting restore failed:",f)}},f=()=>p&&!w(t.art)&&en.get(r)===h;for(const v of d.items)en.set(v,h);const m=b(t.art).add(()=>{p=!1;for(const t of d.items)en.get(t)===h&&en.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!o?.enumerable||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,f),!f())return r;if(t.format(),!f())return r;if(t.createItem(r,!0),!f())return r;if(u=!0,t.render(),!f())return r;p=!1;for(const t of d.items)en.get(t)===h&&en.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const an=new WeakMap;function sn(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",_(r,t)}})}function ln(t,e,r=!1){const n=function(t){const e=en.get(t);return()=>!e||en.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),i=e.$item;let a="selector";st(e,"switch")&&(a="switch"),st(e,"range")&&(a="range"),st(e,"onClick")&&(a="button");const{icons:s,constructor:l}=t.art;if(!n())return;const c=function(t,e,r=b(t)){const n=Nr.get(e);(!n||Er(n)||n.closed)&&Yr(t,e);const o=r.child();return Nr.set(e,o),_r.set(e,r),Wr.set(o,zr(e).events),o.add(()=>{Dr(t,Wr.get(o))}),o}(t.art,e,Or(o)),d=()=>Er(c)&&!w(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(Kr(e),O(p,"art-setting-item"),H(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=ft(p,'
'),u=ft(p,'
'),h=document.createElement("div");switch(O(h,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;_(h,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;_(h,t)}else _(h,s.check)}if(_(n,h),!d())return;sn(e,"icon",h);const f=document.createElement("div");O(f,"art-setting-item-left-text");const m=e.html||"";if(!d())return;_(f,m),_(n,f),sn(e,"html",f);const g=document.createElement("div");O(g,"art-setting-item-right-tooltip");const v=e.tooltip||"";if(!d())return;switch(_(g,v),_(u,g),sn(e,"tooltip",g),a){case"switch":{const t=document.createElement("div");O(t,"art-setting-item-right-icon");const r=ft(t,s.switchOn),n=ft(t,s.switchOff),o=e.switch;if(!d())return;H(o?n:r,"display","none"),_(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;Kr(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(H(n,"display","none"),H(r,"display",null)):(H(n,"display",null),H(r,"display","none"))}});break}case"range":{const t=document.createElement("div");O(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",_(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,i,String(t))}O(r,"art-setting-range"),_(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Kr(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),it(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(e.selector?.length){const t=document.createElement("div");O(t,"art-setting-item-right-icon"),_(t,s.arrowRight),_(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=Vr(e),a=(t,r,n)=>Hr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>Qr(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>Qr(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return Qr(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&O(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>Qr(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,p,a),!d())return;it(e,"$item",{configurable:!0,get:()=>p}),r&&i?.parentNode?i.replaceWith(p):_(o,p),e.mounted&&d()&&Pt(c,()=>{if(!w(t.art))try{const r=e.mounted?.call(t.art,p,e);Promise.resolve(r).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(r){console.warn("ArtPlayer setting mounted failed:",r)}},0)}catch(u){try{c.dispose()}catch(h){console.warn("ArtPlayer setting cleanup failed:",h)}throw p.remove(),u}}function cn(t,e=t.option){if(w(t.art))return;const r=t.cache.get(e);if(r&&!Er(Or(r)))return;const n=(an.get(t)||0)+1;an.set(t,n);const o=()=>an.get(t)===n&&!w(t.art),i=t.active,a=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),s=()=>{t.active=i,i&&t.cache.has(i)&&D(t.cache.get(i),"art-current");for(const[e,r,n]of a)t.$parent.style.setProperty(e,r,n)};if(t.active=e,r)try{D(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!Or(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=b(t.art).child();return Rr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),i=()=>!n.closed&&!w(t.art)&&t.cache.get(e)===r,a=[];try{if(!i())return;O(r,"art-setting-panel"),_(t.$parent,r),D(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Lr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=b(e).child(),n=(t,n)=>{if(r.closed||w(e))return;const o=(...t)=>{if(!r.closed&&!w(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=P(r,e.controls.setting),o=P(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||w(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),jr(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),jr(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(Q(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),jr(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{jr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Ar(e,t)}check(t){!function(t,e){e?.$parent&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&D(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Lr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nzr(t).parent},$parents:{get:()=>zr(t).parents},$option:{get:()=>zr(t).option},$events:{get:()=>zr(t).events},$formatted:{get:()=>!0}}),Cr.set(t,{parent:r,parents:n,option:o,events:a?.events||[],owner:i}),p.generated&&(t.name=e)}for(const p of a)p.generated||o.push(p.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Ar(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){qr(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Ir(n)}catch(i){r.push(i)}}try{Yr(t.art,e)}catch(i){i instanceof f?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new f(r)}(this,t)}remove(t){const e=this.find(t);X(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Xr(t),nn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>n?.remove(),()=>this.render()])try{a()}catch(i){i instanceof f?o.push(...i.errors):o.push(i)}if(o.length)throw new f(o)}update(t){return on(this,t)}add(t,e=this.option){if(w(this.art))return t;let r=!1;this.traverse(e=>{r||(r=e===t)});const n=e.length,o=r?void 0:function(t){const e={};Ur.set(t,e);const r=()=>Ur.get(t)===e;return{current:r,finish(){r()&&Ur.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(w(this.art)||o&&!o.current())throw a;if(e[n]===t&&e.splice(n,1),!r&&i){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw a}finally{o?.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");H(i,"height",`${o}px`),O(i,"art-setting-item"),O(i,"art-setting-item-back");const a=ft(i,'
'),s=document.createElement("div");O(s,"art-setting-item-left-icon"),_(s,n),_(a,s),_(a,e.$parent.html),Hr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Or(r)),_(r,i)}(this,t)}createItem(t,e=!1){ln(this,t,e)}render(t=this.option){cn(this,t)}}class un{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch{return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch{this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch{delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch{this.settings={}}}}const hn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class fn{constructor(t){this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope)?.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}async run(t){if(this.active)try{return await Promise.race([t(),this.cancelled])}finally{this.cancel()}}}const mn=new WeakMap;function gn(t){return mn.get(t)}function vn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const yn=Ct;class bn extends yn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=b(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return mn.set(t,n),r.add(()=>{vn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){return this.art.template.$video?.textTracks?.[0]}get activeCues(){return Array.from(this.textTrack?.activeCues||[])}get cues(){return Array.from(this.textTrack?.cues||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?j(r,t):H(r,t,e)}update(){!function(t){const e=gn(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?ot(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i={...o.subtitle,...e,url:t},a=gn(this),s=a.revision+1,l=await this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),l}createTrack(t,e){!function(t,e,r){const n=gn(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),p=n.scope.child();p.add(()=>{d.onload=null,d.onerror=null});let u=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{p.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{p.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},p.closed||n.trackRevision!==o)return void p.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{p.closed||a.$track!==d||t.update()}):()=>{};if(p.add(()=>{i.events.remove(c)}),p.closed||n.trackRevision!==o)return p.dispose(),void d.remove();const h=n.track;n.track=p,t.destroyEvent=c,s.onload=null,s.onerror=null,u=!0;try{h?.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&vn(n)}}catch(h){if(u)throw h;if(p.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,c?.parentNode===l?c:null),h}}(this,t,e)}async init(t){const e=gn(this),r=function(t){const e=t.request,r=new fn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:i}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Et.subtitle),!t.url)return;let a;this.option=t,this.style(t.style);try{if(!r.active)return;const n=await fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const o=await n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||K(e.url)){case"srt":return{vtt:e.onVttLoad(dt(r))};case"ass":return{vtt:e.onVttLoad(ut(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const l=void 0===s?t.url:a=pt(s.vtt);if(!r.active)return;i.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return a&&(e.ownedURL=a,a=void 0),l}catch(s){if(!r.active)return;throw i.innerHTML="",n.show=s,s}finally{a&&(e.scope.closed||this.url!==a?URL.revokeObjectURL(a):e.ownedURL=a)}})}}const wn=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${i}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class xn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=R(e.container),X(this.$container,`No container element found by ${e.container}`)),X(M(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();X("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),X(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=v.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=y(t);o.rollback=r,v.set(e,t),o.releaseContainer=()=>{v.get(e)===t&&v.delete(e)}}(t,this.$container,tn(this.$container)),function(t,e,r){const n=y(t),o=n.mountingTemplate;n.mountingTemplate=e;try{r()}finally{n.mountingTemplate=o}}(t,this,()=>{this.$container.dataset.artId=String(t.id),this.init()})}static get html(){return wn}query(t){return R(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=xn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);if(w(this.art))return;!function(t){X(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),F(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&O(this.$player,"art-backdrop"),p&&O(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":O(this.$player,"art-destroy")}}const kn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class $n{on(t,e,r){const n=this.e||(this.e={});let o=kn(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(kn(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=kn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new xn(this),b(this).closed)return;if(this.events=new ae(this),b(this).closed)return;if(this.storage=new un,b(this).closed)return;if(this.icons=new fe(this),b(this).closed)return;if(this.i18n=new ue(this),b(this).closed)return;if(this.notice=new ke(this),b(this).closed)return;if(this.player=new cr(this),b(this).closed)return;if(this.layers=new ve(this),b(this).closed)return;if(this.controls=new Kt(this),b(this).closed)return;if(this.contextmenu=new Lt(this),b(this).closed)return;if(this.subtitle=new bn(this),b(this).closed)return;if(this.info=new ge(this),b(this).closed)return;if(this.loading=new ye(this),b(this).closed)return;if(this.hotkey=new de(this),b(this).closed)return;if(this.mask=new be(this),b(this).closed)return;if(this.setting=new pn(this),b(this).closed)return;if(this.plugins=new kr(this),b(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Cn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Cn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=y(t);return e.rollback=void 0,!e.scope.closed})(this)&&Tn.push(this)}catch(r){try{x(this,Tn,!0,Cn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return Tn}static get version(){return i}static get config(){return h}static get utils(){return ht}static get scheme(){return Et}static get Emitter(){return $n}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return xn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:l?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:navigator?.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){x(this,Tn,t,Cn.REMOVE_SRC_WHEN_DESTROY)}}var Ln,Sn;return Cn.STYLE=hn,Cn.DEBUG=!1,Cn.CONTEXTMENU=!0,Cn.NOTICE_TIME=2e3,Cn.SETTING_WIDTH=250,Cn.SETTING_ITEM_WIDTH=200,Cn.SETTING_ITEM_HEIGHT=35,Cn.RESIZE_TIME=200,Cn.SCROLL_TIME=200,Cn.SCROLL_GAP=50,Cn.AUTO_PLAYBACK_MAX=10,Cn.AUTO_PLAYBACK_MIN=5,Cn.AUTO_PLAYBACK_TIMEOUT=3e3,Cn.RECONNECT_TIME_MAX=5,Cn.RECONNECT_SLEEP_TIME=1e3,Cn.CONTROL_HIDE_TIME=3e3,Cn.DBCLICK_TIME=300,Cn.DBCLICK_FULLSCREEN=!0,Cn.MOBILE_DBCLICK_PLAY=!0,Cn.MOBILE_CLICK_PLAY=!1,Cn.AUTO_ORIENTATION_TIME=200,Cn.INFO_LOOP_TIME=1e3,Cn.FAST_FORWARD_VALUE=3,Cn.FAST_FORWARD_TIME=1e3,Cn.TOUCH_MOVE_RATIO=.5,Cn.VOLUME_STEP=.1,Cn.SEEK_STEP=5,Cn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Cn.ASPECT_RATIO=["default","4:3","16:9"],Cn.FLIP=["normal","horizontal","vertical"],Cn.FULLSCREEN_WEB_IN_BODY=!0,Cn.LOG_VERSION=!0,Cn.USE_RAF=!1,Cn.REMOVE_SRC_WHEN_DESTROY=!0,Ln=Cn,Sn=hn,u&&(window.Artplayer=Ln,a("artplayer-style",Sn),setTimeout(()=>{Ln.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Ln.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Cn}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),c=/^(?:(?!chrome|android).)*safari/i.test(s),l=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=l||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,u=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,p="undefined"!==typeof window&&"undefined"!==typeof document;const f={properties:["audioTracks","autoplay","buffered","controller","controls","crossOrigin","currentSrc","currentTime","defaultMuted","defaultPlaybackRate","duration","ended","error","loop","mediaGroup","muted","networkState","paused","playbackRate","played","preload","readyState","seekable","seeking","src","startDate","textTracks","videoTracks","volume"],methods:["addTextTrack","canPlayType","load","play","pause"],events:["abort","canplay","canplaythrough","durationchange","emptied","ended","error","loadeddata","loadedmetadata","loadstart","pause","play","playing","progress","ratechange","seeked","seeking","stalled","suspend","timeupdate","volumechange","waiting"],prototypes:["width","height","videoWidth","videoHeight","poster","webkitDecodedFrameCount","webkitDroppedFrameCount","playsInline","webkitSupportsFullscreen","webkitDisplayingFullscreen","onenterpictureinpicture","onleavepictureinpicture","disablePictureInPicture","cancelVideoFrameCallback","requestVideoFrameCallback","getVideoPlaybackQuality","requestPictureInPicture","webkitEnterFullScreen","webkitEnterFullscreen","webkitExitFullScreen","webkitExitFullscreen"]};class h extends Error{constructor(t){super("Failed to release ArtPlayer resources"),this.errors=t,this.name="ResourceCleanupError"}}class m{constructor(){this.cleanups=new Set,this.disposed=!1}get closed(){return this.disposed}add(t){let e=!0;const r=()=>{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new m,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof h?t.push(...e.errors):t.push(e)}if(t.length)throw new h(t)}}const g=new WeakMap,v=new WeakMap;function y(t){const e=g.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function b(t){return y(t).scope}function w(t){const e=y(t);return e.destroying||e.scope.closed}function x(t,e,r,n,o=!1){const i=y(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],s=t=>{try{t()}catch(e){a.push(...e instanceof h?e.errors:[e])}};n&&t.template?.$video&&s(()=>t.reset()),s(()=>i.scope.dispose()),s(()=>(t.template||i.mountingTemplate)?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),s(()=>t.emit("destroy")),s(()=>i.finalizers.dispose()),o&&i.rollback&&s(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const l of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",l);if(a.length)throw a[0]}const k=new WeakMap;function $(t,e){const r=b(t).child();return k.set(e,r),r}function E(t){const e=k.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function A(t){k.get(t)?.dispose()}function C(t,e,r,n){const o=E(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function S(t,e){return{on:(r,n)=>{C(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=E(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}function T(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode??null;return"undefined"===typeof window||e.includes(window)||e.push(window),e}function L(t,e){return T(t).includes(e)}function P(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function M(t){return t.getBoundingClientRect()}function z(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;";try{document.body.appendChild(t);const e=getComputedStyle(t);return{top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0}}finally{t.remove()}}function R(t,e=document){return e.querySelector(t)}function O(t,e){return t.classList.add(e)}function D(t,e){return t.classList.remove(e)}function I(t,e){return t.classList.contains(e)}function N(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function _(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function W(t,e){_(t).forEach(t=>D(t,e)),O(t,e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function V(t){return document.createElement(t)}function Y(t,e,r="top"){u||(t.setAttribute("aria-label",e),O(t,"hint--rounded"),O(t,`hint--${r}`))}function B(t="",e=""){const r=V("i");return O(r,"art-icon"),O(r,`art-icon-${t}`),N(r,e),r}function H(t,e,r){return t.style[e]=r,t}function j(t,e){for(const r in e)H(t,r,e[r]);return t}function q(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new m;let a=!1,s=()=>{};function c(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function l(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void l(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const c=new Image;d(c,()=>l(c)),i.closed||(c.src=e)}catch(e){c(e)}}))}),i.closed||(n.src=t)}catch(u){c(u)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){c(u)}},e.onerror=()=>c(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}class U extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function X(t,e){if(!t)throw new U(e);return t}function G(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function K(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function Z(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function J(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function Q(t){return t.charAt(0).toUpperCase()+t.slice(1)}function tt(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const et={"&":"&","<":"<",">":">","'":"'",'"':"""},rt={"&":"&","<":"<",">":">","'":"'",""":'"'},nt=/(&|<|>|'|")/g;function ot(t){return t.replace(/[&<>'"]/g,t=>et[t]||t)}const it=Object.defineProperty,{hasOwnProperty:at}=Object.prototype;function st(t,e){return at.call(t,e)}function ct(t,e){return Object.getOwnPropertyDescriptor(t,e)}function lt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?lt(o,i):i,it(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function dt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function ut(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function pt(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const ft=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:U,addClass:O,append:N,assToVtt:pt,capitalize:Q,clamp:J,createElement:V,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:it,download:Z,errorHandle:X,escape:ot,get:ct,getComposedPath:T,getExt:K,getIcon:B,getRect:M,getSafeAreaInsets:z,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:I,includeFromEvent:L,inverseClass:W,isBrowser:p,isIOS:l,isIOS13:d,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:u,isSafari:c,loadImg:function(t,e){return q(t,e,void 0)},mergeDeep:lt,query:R,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:D,replaceElement:F,secondToTime:tt,setStyle:H,setStyleText:a,setStyles:j,siblings:_,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:P,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:Y,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:s,vttToBlob:ut},Symbol.toStringTag,{value:"Module"}));function ht(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let c=()=>{};function l(e){a&&c(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,l,o),c=t.add(()=>{try{e.removeEventListener(r,l,i)}finally{s?.removeEventListener("abort",c)}}),s?.addEventListener("abort",c,{once:!0}),c}function mt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function gt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const vt=new WeakSet;function yt(t){vt.add(t),t.preventDefault()}function bt(t){return!t.altKey&&!t.ctrlKey&&!t.metaKey&&!t.isComposing&&229!==t.keyCode}function wt(t,e,r=()=>e.click(),n=()=>!0){if(t.closed)return;e.hasAttribute("role")||e.setAttribute("role","button"),e.hasAttribute("tabindex")||(e.tabIndex=0);let o=!1;const i=()=>n()&&"true"!==e.getAttribute("aria-disabled")&&!e.hasAttribute("disabled"),a=t=>(t.composedPath()[0]||t.target)===e;ht(t,e,"keydown",t=>{const e=t;a(e)&&bt(e)&&!e.defaultPrevented&&("Enter"===e.key?(yt(e),!e.repeat&&i()&&r()):" "===e.key&&(yt(e),!e.repeat&&i()&&(o=!0)))}),ht(t,e,"keyup",t=>{const n=t;if(" "!==n.key)return;const s=o;o=!1,s&&a(n)&&bt(n)&&!n.defaultPrevented&&i()&&e.ownerDocument.activeElement===e&&(yt(n),r())}),ht(t,e,"blur",()=>{o=!1}),t.add(()=>{o=!1})}function xt(t,e){return N(t,e)}function kt(t,e){return e.querySelector(t)}const $t=new WeakSet;function Et(t){const e=t.template.$player;!w(t)&&e.isConnected&&(e.hasAttribute("tabindex")||(e.setAttribute("tabindex","-1"),$t.has(e)||($t.add(e),b(t).add(()=>{$t.delete(e),"-1"===e.getAttribute("tabindex")&&e.removeAttribute("tabindex")}))),e.focus({preventScroll:!0}))}const At=new WeakSet,Ct="[tabindex],button,input,select,textarea,a[href],[contenteditable]";function St(t){return[t,...t.querySelectorAll(Ct)].find(t=>{if(!t.matches(Ct)||t.tabIndex<0||t.matches(":disabled")||t.closest("[inert]")||"true"===t.getAttribute("aria-disabled")||!t.getClientRects().length)return!1;const e=t.ownerDocument.defaultView?.getComputedStyle(t);return"hidden"!==e?.visibility&&"collapse"!==e?.visibility})}function Tt(t,e,r){const n=e?.ownerDocument,o=n?.activeElement;if(!["control","contextmenu"].includes(t.name??"")||At.has(t)||!e||!n||!o||!e.contains(o))return()=>{};const i=t.art.template.$player,a=Array.from(i.querySelectorAll(`.art-${t.name}`)),s=a.indexOf(e),c=[...a.slice(s+1),...a.slice(0,s).reverse()];return At.add(t),()=>{if(At.delete(t),w(t.art)||!i.isConnected||n.activeElement!==n.body)return;const e=r?t.cache.get(r)?.$ref:void 0;for(const t of[...e?[e]:[],...c]){if(!i.contains(t))continue;const e=St(t);if(e)return void e.focus({preventScroll:!0})}Et(t.art)}}const Lt="array",Pt="boolean",Mt="string",zt="number",Rt="object",Ot="function";function Dt(t,e,r){return X(e===Mt||e===zt||t instanceof Element,`${r.join(".")} require '${Mt}' or 'Element' type`)}const It={html:Dt,disable:`?${Pt}`,name:`?${Mt}`,index:`?${zt}`,style:`?${Rt}`,click:`?${Ot}`,mounted:`?${Ot}`,tooltip:`?${Mt}|${zt}`,width:`?${zt}`,selector:`?${Lt}`,onSelect:`?${Ot}`,switch:`?${Pt}`,onSwitch:`?${Ot}`,range:`?${Lt}`,onRange:`?${Ot}`,onChange:`?${Ot}`},Nt={id:Mt,container:Dt,url:Mt,poster:Mt,type:Mt,theme:Mt,lang:Mt,volume:zt,isLive:Pt,muted:Pt,autoplay:Pt,autoSize:Pt,autoMini:Pt,loop:Pt,flip:Pt,playbackRate:Pt,aspectRatio:Pt,screenshot:Pt,setting:Pt,hotkey:Pt,pip:Pt,mutex:Pt,backdrop:Pt,fullscreen:Pt,fullscreenWeb:Pt,subtitleOffset:Pt,miniProgressBar:Pt,useSSR:Pt,playsInline:Pt,lock:Pt,gesture:Pt,fastForward:Pt,autoPlayback:Pt,autoOrientation:Pt,airplay:Pt,proxy:`?${Ot}`,plugins:[Ot],layers:[It],contextmenu:[It],settings:[It],controls:[{...It,position:(t,e,r)=>{const n=["top","left","right"];return X("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${Pt}`,html:Mt,url:Mt}],highlight:[{time:zt,text:Mt}],thumbnails:{url:Mt,number:zt,column:zt,width:zt,height:zt,scale:zt},subtitle:{url:Mt,name:Mt,type:Mt,style:Rt,escape:Pt,encoding:Mt,onVttLoad:Ot},moreVideoAttr:Rt,i18n:Rt,icons:Rt,cssVar:Rt,customType:Rt},_t=new WeakSet;class Wt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return I(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?O(e,r):D(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(w(this.art))return;const e="function"===typeof t?t(this.art):t;if(w(this.art))return;if(e.html=e.html||"",o(e,It),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;X(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=$(this.art,i),s=[],c=Object.getOwnPropertyDescriptor(this,r);let l=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){O(t,`art-${r}`),O(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):N(e,t),i.html&&N(t,i.html),i.style&&j(t,i.style),i.tooltip&&Y(t,i.tooltip)}(i,this.$parent,this.name,r,this.id,e),a.closed)return;if(e.click){("control"===this.name&&!e.selector||"contextmenu"===this.name&&!i.querySelector("[data-value]"))&&!i.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")&&wt(a,i);const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,r,i),l=!0,n.set(r,{$ref:i,events:s,option:e}),e.mounted&&e.mounted.call(this.art,i),i}catch(d){try{A(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw n.get(r)?.$ref===i&&n.delete(r),l&&this[r]===i&&(c?Object.defineProperty(this,r,c):delete this[r]),i.remove(),d}}remove(t){X(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(_t.has(e))return;const r=Tt(this,e.$ref);_t.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{A(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{_t.delete(e),r()}}update(t){const e=Tt(this,this.cache.get(t.name)?.$ref,t.name);try{if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}finally{e()}}}function Ft(t){for(const e of t.querySelectorAll("[data-value]"))e.setAttribute("aria-pressed",String(e.classList.contains("art-current")))}function Vt(t,e){const r=E(t);if(!r.closed){t.setAttribute("role","group"),t.setAttribute("aria-label",e);for(const n of t.querySelectorAll("[data-value]"))wt(r,n),n.setAttribute("aria-label",`${e}: ${n.textContent?.trim()??""}`);Ft(t)}}const Yt=new WeakMap;function Bt(t,e){e?Yt.set(t,e):Yt.delete(t)}function Ht(t){const e=new Set;let r=t;for(;!e.has(r);){e.add(r);let t,n=r;for(;n&&!t;)t=Yt.get(n),n=n.parentElement;if(!t)return r;r=t}return t}function jt(t){const e=t;return!!e&&(["INPUT","TEXTAREA","SELECT"].includes(e.tagName)||e.isContentEditable)}function qt(t){const e=t.ownerDocument.defaultView?.getComputedStyle(t).visibility;return t.isConnected&&!t.matches(":disabled")&&!t.closest("[inert]")&&"true"!==t.getAttribute("aria-disabled")&&t.getClientRects().length>0&&"hidden"!==e&&"collapse"!==e}class Ut extends Wt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,$(t,this.$parent),u||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=S(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join(""),i=r.get("Play Speed");return{...t,html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=S(e,t),n=R('[data-value="1"]',t);n&&W(n,"art-current"),Vt(t,i),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&(W(r,"art-current"),Ft(t))})}}}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join(""),i=r.get("Aspect Ratio");return{...t,html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=S(e,t),n=R('[data-value="default"]',t);n&&W(n,"art-current"),Vt(t,i),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&(W(r,"art-current"),Ft(t))})}}}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(Q(t))}`).join(""),i=r.get("Video Flip");return{...t,html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=S(e,t),n=R('[data-value="normal"]',t);n&&W(n,"art-current"),Vt(t,i),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&(W(r,"art-current"),Ft(t))})}}}}({name:"flip",index:30})),this.add(function(t){return e=>({...t,html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return{...t,html:`ArtPlayer ${i}`}}({name:"version",index:50})),this.add(function(t){return e=>({...t,html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{this.show=!0,a.closed||w(this.art)||!this.show||function(t,e,r){const{$player:n,$contextmenu:o}=t.template,{height:i,width:a,left:s,top:c}=M(n),{height:l,width:d}=M(o);let u=e-s,p=r-c;e+d>s+a&&(u=a-d),r+l>c+i&&(p=i-l),w(t)||j(o,{top:`${p}px`,left:`${u}px`})}(this.art,t,e)},c=function(t,e){const{art:r}=t,{$player:n,$contextmenu:o}=r.template,i=E(o),a=()=>!i.closed&&!w(r);let s,c=!1,l="",d=0;const u=()=>{const t=n.ownerDocument.activeElement;s=t&&n.contains(t)?Ht(t):n,Bt(o,s)},p=()=>Array.from(o.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]")).filter(t=>t.tabIndex>=0&&qt(t)),f=r.i18n.get("Context Menu");if(!a())return{pointer:()=>!1};o.setAttribute("role","group"),o.setAttribute("aria-label",f);const h=t=>{if(!a())return;if(t)return void(o.contains(n.ownerDocument.activeElement)||u());const e=n.ownerDocument.activeElement,i=o.contains(e)||c&&e===n.ownerDocument.body,d=s;s=void 0,c=!1,l="",Bt(o),i&&(d&&n.contains(d)&&qt(d)&&d.focus({preventScroll:!0}),(n.ownerDocument.activeElement===n.ownerDocument.body||o.contains(n.ownerDocument.activeElement))&&Et(r))};r.on("contextmenu",h),i.add(()=>{r.off("contextmenu",h),Bt(o)}),ht(i,o,"focusin",()=>{c=!0});let m=!1;return ht(i,o,"focusout",e=>{o.contains(e.relatedTarget)||m||(m=!0,mt(i,()=>{m=!1,a()&&t.show&&!o.contains(n.ownerDocument.activeElement)&&(t.show=!1)},0))}),ht(i,n,"keydown",n=>{const i=n;if(!a()||!bt(i)||i.defaultPrevented)return;if(("ContextMenu"===i.key||"F10"===i.key&&i.shiftKey)&&r.constructor.CONTEXTMENU&&!jt(i.target)){yt(i),u();const r=i.target.getBoundingClientRect();return e(r.left,r.bottom),void(a()&&t.show&&p()[0]?.focus({preventScroll:!0}))}if(!t.show||!o.contains(i.target))return;if("Escape"===i.key)return yt(i),void(t.show=!1);if("Tab"===i.key)return void(t.show=!1);if(jt(i.target))return;const s=p(),c=s.indexOf(i.target);let f;if("ArrowDown"===i.key||"ArrowRight"===i.key)f=s[(c+1)%s.length];else if("ArrowUp"===i.key||"ArrowLeft"===i.key)f=s[(c+s.length-1)%s.length];else if("Home"===i.key)f=s[0];else if("End"===i.key)f=s[s.length-1];else{if(1!==i.key.length||" "===i.key)return;{const t=i.key.toLowerCase();l=Date.now()-d>700?t:l+t,d=Date.now();const e=[...l].every(e=>e===t)?t:l;f=[...s.slice(c+1),...s.slice(0,c+1)].find(t=>(t.getAttribute("aria-label")||t.textContent||"").trim().toLowerCase().startsWith(e))}}yt(i),f?.focus({preventScroll:!0})}),{pointer:t=>!(!a()||!r.constructor.CONTEXTMENU||jt(t.target))&&(u(),!0)}}(this,s);o(e,"contextmenu",t=>{c.pointer(t)&&(t.preventDefault(),s(t.clientX,t.clientY))}),o(e,"click",t=>{L(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}const Xt=new WeakMap,Gt=new WeakMap,Kt=new WeakMap;function Zt(t){return Kt.get(t)||b(t)}function Jt(t){const e=Xt.get(t),r=Kt.get(t);return()=>Xt.get(t)===e&&(!e||e.active())&&Kt.get(t)===r&&(!r||!r.closed)}function Qt(t){const e=Kt.get(t),r=b(t).child(),n=r.child();Kt.set(t,r),r.add(()=>{Kt.get(t)===r&&Kt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!w(t)&&!n.closed&&Xt.get(t)===o};return Xt.set(t,o),n.add(()=>{Xt.get(t)===o&&Xt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function te(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function ee(t,e,r){Gt.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Gt.get(t)===e&&(Gt.delete(t),te(e))}}function re(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function ne(t,e){const{$progress:r}=t.template,{left:n}=M(r),o=J((u?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:tt(i),width:o,percentage:J(o/r.clientWidth,0,1)}}function oe(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=ne(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}const ie=new Map([["ArrowRight",1],["ArrowUp",1],["ArrowLeft",-1],["ArrowDown",-1],["PageUp",10],["PageDown",-10]]);function ae(t,e,r,n,o,i="horizontal"){const a=t=>[t.min,t.max,t.value,t.step].every(Number.isFinite)&&t.max>t.min&&t.step>0,s=(t,e)=>Math.min(e.max,Math.max(e.min,t)),c=()=>{if(t.closed)return;const r=n(),o=a(r),i=o?s(r.value,r):0;e.setAttribute("aria-disabled",String(!o)),e.setAttribute("aria-valuemin",String(o?r.min:0)),e.setAttribute("aria-valuemax",String(o?r.max:0)),e.setAttribute("aria-valuenow",String(i)),e.setAttribute("aria-valuetext",r.text(i))};return t.closed||(e.setAttribute("role","slider"),e.tabIndex=0,e.setAttribute("aria-label",r),e.setAttribute("aria-orientation",i),ht(t,e,"keydown",t=>{const r=t;if((r.composedPath()[0]||r.target)!==e||!bt(r)||r.defaultPrevented)return;const i=ie.get(r.key);if(void 0===i&&"Home"!==r.key&&"End"!==r.key)return;yt(r);const l=n();if(!a(l))return void c();const d="Home"===r.key?l.min:"End"===r.key?l.max:s(l.value,l)+i*l.step;o(s(d,l)),c()}),c()),c}const se=new WeakMap;function ce(t){return se.get(t)||0}function le(t,e,r){let n,o=!1,i=!1,a=!1,s=ce(t);const c=()=>a||ce(t)!==s,l=()=>!!t.template?.$video?.seeking;return{restore(i=()=>{t.currentTime=e}){if(!r()||c())return;const d=ce(t);i(),s=ce(t),s>d+1&&(a=!0),r()&&(n=t.currentTime,r()&&!c()&&(o=l()))},manual(){a=!0},ready(){if(!r()||l())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!c()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!l()}}}function de(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=E(e),{on:a}=S(t,e);let s=()=>{};const c=kt(".art-progress-hover",e),l=kt(".art-progress-loaded",e),d=kt(".art-progress-played",e),p=kt(".art-progress-highlight",e),f=kt(".art-progress-indicator",e),h=kt(".art-progress-tip",e);function m(r,n){const{width:o,time:i}=n||ne(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?H(h,"left",0):o>e.clientWidth-a/2?H(h,"left",e.clientWidth-a+"px"):H(h,"left",o-a/2+"px")}r.indicator?N(f,r.indicator):H(f,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const g="played"===r&&a&&u;if("loaded"===r&&H(l,"width",100*n+"%"),"hover"===r&&(H(c,"width",100*n+"%"),L(a,p)?function(r){const{width:n}=ne(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const i=h.clientWidth;n<=i/2?H(h,"left",0):n>e.clientWidth-i/2?H(h,"left",e.clientWidth-i+"px"):H(h,"left",n-i/2+"px")}(a):m(a),0===n?D(o,"art-progress-hover"):O(o,"art-progress-hover")),"played"===r&&(H(d,"width",100*n+"%"),H(f,"left",100*n+"%")),g){O(o,"art-progress-hover");m(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=mt(i,()=>{D(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){p.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function ue(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{de(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=S(t,e),a=E(e);let s=0;const c=()=>{const e=Jt(t);return()=>!a.closed&&!w(t)&&e()},l=()=>{const t=++s,e=c();return()=>t===s&&e()};if(!u){let e;i(r,"click",e=>{e.target!==n&&oe(t,e,l())}),i(r,"mousemove",e=>{const r=c(),{percentage:n}=ne(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?l():void 0}),o("document:mousemove",r=>{const n=e;if(n?.()){const{second:o,percentage:i}=ne(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t),function(t,e){const r=E(e),{on:n}=S(t,e);let o,i=0;const a=ae(r,e,t.i18n.get("Progress"),()=>({min:0,max:t.duration,value:t.currentTime,step:t.constructor.SEEK_STEP,text:e=>`${tt(e)} / ${tt(Number.isFinite(t.duration)&&t.duration>0?t.duration:0)}`}),e=>{const n=++i;o?.dispose();const s=r.child();o=s;const c=Zt(t).add(()=>{s.dispose()});s.add(()=>{c()}),s.add(()=>{o===s&&(o=void 0)});const l=Jt(t),d=()=>n===i&&!s.closed&&!w(t)&&l(),u=le(t,e,d),p=()=>{d()?u.ready()&&(s.dispose(),a()):s.dispose()};for(const r of["video:seeked","video:ended"])t.on(r,p),s.add(()=>{t.off(r,p)});try{t.emit("setBar","played",e/t.duration),d()&&u.restore(()=>{t.seek=e}),p()}catch(f){throw s.dispose(),f}});n("video:loadedmetadata",a),n("video:durationchange",a),n("video:emptied",a),n("video:timeupdate",a),n("video:seeking",a),n("video:seeked",a),n("video:ended",a)}(e,t)}})}function pe(t){const{option:e}=t.art;e.isLive||t.add(ue({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e,a=xt(t,o.play),s=xt(t,o.pause);function c(){t.setAttribute("aria-label",i.get("Play")),H(a,"display","flex"),H(s,"display","none")}function l(){t.setAttribute("aria-label",i.get("Pause")),H(a,"display","none"),H(s,"display","flex")}wt(E(t),t,()=>(e.playing?s:a).click()),Y(a,i.get("Play")),Y(s,i.get("Pause")),n(a,"click",()=>{G(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?l():c(),r("video:playing",()=>{l()}),r("video:pause",()=>{c()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e,a=xt(t,o.volume),s=xt(t,o.volumeClose);for(const e of[a,s])wt(E(t),e),e.setAttribute("aria-label",i.get("Mute"));const c=xt(t,'
'),l=xt(c,'
'),d=xt(l,'
'),p=xt(l,'
'),f=xt(p,'
'),h=xt(f,'
'),m=xt(p,'
'),g=E(t);let v=0;const y=ae(g,p,i.get("Volume"),()=>({min:0,max:100,value:e.muted?0:100*e.volume,step:100*e.constructor.VOLUME_STEP,text:t=>`${Math.round(t)}%`}),t=>{const r=++v;e.muted=!1,r!==v||g.closed||w(e)||(e.volume=t/100)},"vertical");function b(t){const{top:e,height:r}=M(p);return 1-(t.clientY-e)/r}function x(){y();const r=t.ownerDocument.activeElement,n=e.muted||0===e.volume,o=n?s:a;if(a.setAttribute("aria-pressed",String(e.muted)),s.setAttribute("aria-pressed",String(e.muted)),n)H(a,"display","none"),H(s,"display","flex"),H(m,"top","100%"),H(h,"top","100%"),d.textContent="0";else{const t=100*e.volume;H(a,"display","flex"),H(s,"display","none"),H(m,"top",100-t+"%"),H(h,"top",100-t+"%"),d.textContent=String(Math.floor(t))}r!==a&&r!==s||r===o||o.focus({preventScroll:!0})}if(x(),r("video:volumechange",x),n(a,"click",()=>{e.muted=!0}),n(s,"click",()=>{e.muted=!1}),u)H(c,"display","none");else{let t=!1;n(p,"mousedown",r=>{t=0===r.button,e.volume=b(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=b(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>({...t,style:u?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=S(e,t);function n(){const r=`${tt(e.currentTime)} / ${tt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!b(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!u&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=S(e,t),{icons:n}=e;wt(E(t),t),xt(t,n.screenshot),r(t,"click",()=>{G(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e;xt(t,o.setting),wt(E(t),t),t.setAttribute("aria-expanded","false"),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{t.setAttribute("aria-expanded",String(e)),Y(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e;wt(E(t),t),xt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{Y(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=S(e,t),{icons:n}=e;wt(E(t),t),xt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e;wt(E(t),t);const a=xt(t,o.fullscreenWebOn),s=xt(t,o.fullscreenWebOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(Y(t,i.get("Exit Web Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(Y(t,i.get("Web Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=S(e,t),{icons:o,i18n:i}=e;wt(E(t),t);const a=xt(t,o.fullscreenOn),s=xt(t,o.fullscreenOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(Y(t,i.get("Exit Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(Y(t,i.get("Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rme.get(t).option.selector}),it(t,"$control_item",{get:()=>me.get(t).item}),it(t,"$control_value",{get:()=>me.get(t).value})),me.set(t,e)}function ve(t,e){t.innerHTML=e}function ye(t,e,r,n,o){const{proxy:i}=t.events,a=E(n),s=r.selector;O(n,"art-control-selector");const c=document.createElement("div");O(c,"art-selector-value"),N(c,r.html),n.textContent="",N(n,c);const l=xt(n,'
');for(let f=0;f{if(a.closed)return;const o=T(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++d,l=()=>!a.closed&&s===d,u=a.add(function(t,e){return fe.set(t,e),()=>{fe.get(t)===e&&fe.delete(t)}}(n,l));try{if(e(i),a.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,i,i.$control_item,n);if(l()){const t=c.contains(c.ownerDocument.activeElement);ve(c,e),me.get(i)?.refresh?.(t)}}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{u()}});o.push(u);const p=function(t,e,r,n,o){if(t.closed)return()=>{};const i=Array.from(n.children),a=i.some(t=>t.querySelector(he));n.setAttribute("role",a?"group":"listbox"),n.setAttribute("aria-label",o);let s=!1,c=!1,l=!1,d="",u=0;const p=()=>i.length>0&&(c||s&&!l),f=()=>r.querySelector('button,a[href],[role="button"]')||r,h=(e=!1)=>{if(t.closed)return;const n=f();r.querySelector(he)?(r.removeAttribute("role"),r.removeAttribute("tabindex")):(r.setAttribute("role","button"),r.tabIndex=0),n!==r&&(r.removeAttribute("aria-haspopup"),r.removeAttribute("aria-expanded"),r.removeAttribute("aria-disabled")),a?n.removeAttribute("aria-haspopup"):n.setAttribute("aria-haspopup","listbox"),n.setAttribute("aria-expanded",String(p())),n.setAttribute("aria-disabled",String(0===i.length)),e&&r.isConnected&&r.ownerDocument.activeElement===r.ownerDocument.body&&n.focus({preventScroll:!0})},m=(t,r=!1)=>{c=t,l=r,e.classList.toggle("art-selector-open",t),e.classList.toggle("art-selector-dismissed",r),h()},g=e=>{e&&!t.closed&&((e.querySelector(he)||e).focus({preventScroll:!0}),t.closed||e.scrollIntoView({block:"nearest",inline:"nearest"}))},v=(e=!1)=>{!t.closed&&i.length&&(m(!0),d="",g(i.find(t=>t.classList.contains("art-current"))||i[e?i.length-1:0]))},y=()=>{if(t.closed)return;const o=n.contains(e.ownerDocument.activeElement);m(!1,!0),d="",o&&r.isConnected&&f().focus({preventScroll:!0})};wt(t,r,()=>{r.click(),e.ownerDocument.activeElement===r&&v()}),h();for(const b of i){const e=b.classList.contains("art-current");a?b.setAttribute("aria-current",String(e)):(b.setAttribute("role","option"),b.setAttribute("aria-selected",String(e))),b.querySelector(he)||(b.tabIndex=-1,wt(t,b,()=>{b.click(),y()}))}return ht(t,r,"keydown",t=>{const e=t;!bt(e)||e.defaultPrevented||e.target!==r&&e.target!==f()||("ArrowDown"===e.key||"ArrowUp"===e.key?(yt(e),v("ArrowUp"===e.key)):"Escape"===e.key&&p()&&(yt(e),y()))}),ht(t,r,"click",t=>{t.isTrusted&&0===t.detail&&f()!==r&&v()}),ht(t,n,"keydown",t=>{const e=t;if(!bt(e)||e.defaultPrevented)return;if("Escape"===e.key)return yt(e),void y();const r=i.indexOf(e.target);if(r<0)return;let n;switch(1!==e.key.length&&(d=""),e.key){case"ArrowDown":n=Math.min(r+1,i.length-1);break;case"ArrowUp":n=Math.max(r-1,0);break;case"Home":n=0;break;case"End":n=i.length-1;break;case"ArrowLeft":case"ArrowRight":return void yt(e);default:{if(1!==e.key.length||" "===e.key)return;const t=Date.now();d=t-u<500?d+e.key.toLocaleLowerCase():e.key.toLocaleLowerCase(),u=t;const o=[...d].every(t=>t===d[0])?d[0]:d;for(let e=1;e<=i.length;e++){const t=(r+e)%i.length;if(i[t].textContent?.trim().toLocaleLowerCase().startsWith(o)){n=t;break}}}}yt(e),void 0!==n&&g(i[n])}),ht(t,n,"click",t=>{t.isTrusted&&0===t.detail&&y()}),ht(t,e,"mouseenter",()=>{s=!0,m(c)}),ht(t,e,"mouseleave",()=>{s=!1,m(n.contains(e.ownerDocument.activeElement))}),ht(t,e,"focusout",t=>{e.contains(t.relatedTarget)||m(!1,!0)}),t.add(()=>{e.classList.remove("art-selector-open","art-selector-dismissed")}),h}(a,n,c,l,String(r.tooltip||r.name||c.textContent||t.i18n.get("Open")));for(const f of s)me.get(f).refresh=p}class be extends Wt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template,o=function(t,e,r){let n,o,i=!0;const a=()=>!t.closed&&i&&e.contains(e.ownerDocument.activeElement),s=()=>{const t=a(),n=e.classList.contains("art-keyboard-focus");e.classList.toggle("art-keyboard-focus",t),t&&!n&&r()},c=()=>{i=!0,s()},l=()=>{i=!1,s()},d=()=>{n!==e.ownerDocument&&(o?.dispose(),n=e.ownerDocument,o=t.child(),ht(o,n,"keydown",c,{capture:!0}),ht(o,n,"mousedown",l,{capture:!0}),ht(o,n,"touchstart",l,{capture:!0,passive:!0}))};return d(),ht(t,e,"keydown",c,{capture:!0}),ht(t,e,"mousedown",l,{capture:!0}),ht(t,e,"touchstart",l,{capture:!0,passive:!0}),ht(t,e,"focusin",()=>{d(),s()}),ht(t,e,"focusout",()=>{e.classList.remove("art-keyboard-focus")}),t.add(()=>{e.classList.remove("art-keyboard-focus")}),a}($(t,n),r,()=>{this.show=!0}),{on:i,proxy:a}=S(t,n);a(r,"focusin",e=>{t.isFocus=!0,t.isInput="INPUT"===e.target?.tagName}),a(r,"focusout",e=>{r.contains(e.relatedTarget)||(t.isFocus=!1,t.isInput=!1)}),i("mousemove",()=>{u||(this.show=!0)}),i("click",()=>{u?this.toggle():this.show=!0}),i("document:mousemove",t=>{this.isHover=L(t,n)}),i("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&!o()&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),i("control",t=>{t?(D(r,"art-hide-cursor"),O(r,"art-hover"),this.timer=Date.now()):(O(r,"art-hide-cursor"),D(r,"art-hover"))}),this.init(),b(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=E(e),{on:i}=S(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){pe(this)}add(t){if(w(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:X(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(!t)return;const e=t.$control_value.contains(t.$control_value.ownerDocument.activeElement);ve(t.$control_value,t.html);for(let r=0;rthis.check(t),t,e,r)}}function we(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(w(t))return;const n=L(r,e);t.isInput=n&&"INPUT"===r.target?.tagName,t.isFocus=n,t.emit(n?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),b(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(w(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:c}=r,l=o.filter(t=>n-t<=a);switch(l.length){case 1:if(t.emit("click",e),w(t))return;(!u||!t.isLock&&i)&&G(t.toggle()),o=l;break;case 2:if(t.emit("dblclick",e),w(t))return;u?!t.isLock&&s&&G(t.toggle()):c&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function xe(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!w(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),b(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(w(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:Jt(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{oe(t,i,()=>n(s))}catch(c){throw e===s&&r(),c}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,c=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,c].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const l=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===l||2===l:3===l||4===l))return;const d=J((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=J(i.time+t.duration*d*c,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",J(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${tt(u)} / ${tt(t.duration)}`))},cancel:r}}const ke=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],$e=["resize","scroll","orientationchange"];const Ee=new WeakMap;function Ae(t){const e=Ee.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function Ce(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=Ce(t,e,r,n,o);return i.push(a),a})}catch(f){for(const t of i.reverse())try{t()}catch(h){console.warn("Failed to roll back event listener:",h)}throw f}}const i=r,a=Ae(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(o?.capture),once:Boolean(o?.once),passive:o?.passive,signal:o?.signal},c="boolean"===typeof s?s:s.capture,l="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||l?.aborted)return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,c),l?.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):l?.aborted?p():l?.addEventListener("abort",p,{once:!0})}catch(f){try{u(!0)}catch(h){console.warn("Failed to roll back event listener:",h)}throw f}return p}function Se(t){return(e,r)=>{if(w(t))return;const n=(...e)=>{if(!w(t))return r(...e)};t.on(e,n),b(t).add(()=>{t.off(e,n)})}}function Te(t){if(!t.constructor.USE_RAF)return;const e=b(t);let r=()=>{};const n=()=>{w(t)||(t.playing&&t.emit("raf"),w(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),Se(t)("destroy",()=>r())}class Le{constructor(t){this.destroyEvents=new Set,function(t,e){Ee.set(t,{scope:b(e),cleaning:!1})}(this,t),b(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),we(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{w(t)||(O(r,"art-hover"),t.emit("hover",!0,e))},e=>{w(t)||(D(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{w(t)||t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t,o=Se(t);o("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),w(t)||(t.aspectRatio=e,w(t)||(n.show=""))});const i=b(t);let a=()=>{};const s=()=>{w(t)||(a(),a=mt(i,()=>t.emit("resize"),n.RESIZE_TIME))};o("window:orientationchange",s),o("window:resize",s);const c=t.template.$player.ownerDocument.defaultView?.screen?.orientation;"function"===typeof c?.addEventListener&&e.proxy(c,"change",s)}(t,this),function(t,e){if(!u||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=xe(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=b(t),a=Se(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=o?.innerHeight||n.documentElement.clientHeight,a=o?.innerWidth||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,c=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&c}(n,r.SCROLL_GAP)),w(t)||(s=!0,mt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;b(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){if(w(t))return;const a=++n,s={disposers:[]},c=()=>a!==n||w(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,a=i.window||n.ownerDocument?.defaultView||window,l=(n,o,i)=>{for(const a of o){if(c())return;s.disposers.push(e.proxy(n,a,e=>{r!==s||w(t)||t.emit(`${i}:${a}`,e)}))}};l(o,ke,"document"),l(a,$e,"window")}catch(d){throw o(s),d}if(c())return void o(s);const l=r;r=s,o(l)}i(),e.bindGlobalEvents=i}(t,this),Te(t)}proxy(t,e,r,n={}){return Array.isArray(e),Ce(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=Ae(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function Pe(t){if(t&&1===t.nodeType)return t}function Me(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}function ze(t,e){if(function(t){return vt.has(t)}(t)||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const r=function(t,e){const r=t.target;return 9===r?.nodeType?r:r?.ownerDocument||t.view?.document||e}(t,e);let n=Pe(r.activeElement);for(;n?.shadowRoot?.activeElement;)n=Pe(n.shadowRoot.activeElement);if(n&&Me(n))return!1;const o=Pe(t.composedPath?.()[0])||Pe(t.target),i="Enter"===t.key||"Enter"===t.code||"NumpadEnter"===t.code;if(i||" "===t.key||"Space"===t.code){const t='button,summary,[role="button"],[role="switch"]'+(i?",a[href]":"");if(o?.closest?.(t)||n?.closest?.(t))return!1}return!o||!Me(o)}const Re=new WeakMap;class Oe{constructor(t){this.art=t,this.keys={},Re.set(this,{subscribed:!1}),u||this.init()}init(){const t=this.art;if(w(t))return;const e=Re.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{G(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!w(t)){if(t.isFocus&&ze(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const De={"Context Menu":"\u5feb\u6377\u83dc\u5355",Lock:"\u9501\u5b9a",Back:"\u8fd4\u56de",Settings:"\u8bbe\u7f6e",Progress:"\u64ad\u653e\u8fdb\u5ea6","Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",De);class Ie{constructor(t){this.art=t,this.languages={"zh-cn":De},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=st(this.languages,t)&&this.languages[t]||{}}get(t){return st(this.language,t)&&this.language[t]||t}update(t){this.languages=lt(this.languages,t),this.init()}}const Ne={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class _e{constructor(t){const e={...Ne,...t.option.icons};for(const r in e)it(this,r,{get:()=>B(r,e[r])})}}const We=new WeakMap;function Fe(t,e,r){const n=()=>!e.closed&&!w(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:c,$video:l}}=t,d=i(c,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)}),function(t,e,r){const{$player:n,$info:o,$infoClose:i}=t.template;if(!o)return;const a=()=>!e.closed&&!w(t),s=()=>n.classList.contains("art-info-show"),c=t.i18n.get("Close");if(!a())return;const l=t.i18n.get("Video Info");if(!a())return;i.setAttribute("aria-label",c),o.setAttribute("role","group"),o.setAttribute("aria-label",l),wt(e,i,()=>i.click(),s),ht(e,o,"keydown",t=>{const e=t;a()&&s()&&bt(e)&&!e.defaultPrevented&&"Escape"===e.key&&(yt(e),r())});const d=e=>{if(!a())return;const r=n.ownerDocument,s=r.activeElement;if(e)o.contains(s)||(We.delete(t),s&&n.contains(s)&&(We.set(t,Ht(s)),n.classList.contains("art-keyboard-focus")&&i.focus({preventScroll:!0})));else{const e=We.get(t);if(We.delete(t),!o.contains(s))return;const i=e&&r.defaultView?.getComputedStyle(e).visibility;e?.isConnected&&n.contains(e)&&e.getClientRects().length&&"hidden"!==i&&"collapse"!==i&&!e.matches(":disabled")&&!e.closest("[inert]")&&"true"!==e.getAttribute("aria-disabled")?e.focus({preventScroll:!0}):Et(t)}};t.on("info",d),e.add(()=>{t.off("info",d)})}(t,e,r);const f=()=>{try{for(const t of u){if(!n())return;const e=Reflect.get(l,t.dataset.video??"undefined");if(!n())return;const r="number"===typeof e?e.toFixed(2):e;if(!n())return;if(t.textContent!==r){const e=null==r?null:`${r}`;if(!n())return;t.textContent=e}}n()&&mt(e,f,a.INFO_LOOP_TIME)}catch(t){o(t)}};n()&&f()}catch(i){o(i)}}const Ve=new WeakMap;class Ye extends Wt{constructor(t){super(t),this.name="info",Ve.set(this,{revision:0}),u||this.init()}init(){const t=Ve.get(this),e=++t.revision;if(t.scope?.dispose(),w(this.art)||t.revision!==e)return;const r=b(this.art).child();t.scope=r,r.add(()=>{t.scope===r&&(t.scope=void 0)}),Fe(this.art,r,()=>{this.show=!1})}}class Be extends Wt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{H(i,"display","none"),H(s,"display",null),w(t)&&(c=!0)};var d;t.on("destroy",l),(d=t,y(d).finalizers).add(()=>{try{c||l()}finally{t.off("destroy",l)}}),w(t)||n.proxy(e.$state,"click",()=>{w(t)||G(t.play())})}}const qe=new WeakMap;function Ue(t){const e=qe.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class Xe{constructor(t){this.art=t,this.timer=null,qe.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),b(t).add(()=>{t.off("destroy",e)}),b(t).add(()=>{this.destroy()})}destroy(){Ue(this)}set show(t){if(w(this.art))return;const e=qe.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){Ue(this);const i=e.revision,a=()=>!w(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(O(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const c={};e.pending=c;const l=setTimeout(()=>{if(w(this.art)||e.pending!==c)return;e.pending=void 0;const t=e.revision;o.textContent="",w(this.art)||e.revision!==t||D(n,"art-notice-show")},s);a()?this.timer=l:clearTimeout(l)}else D(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function Ge(t,e){return function(t,e){const r=lt(e,t);return r.container=t.container,o(r,Nt)}(t,e)}function Ke({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ze(t,e){if(!Ke(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Ke(r)?r:void 0}function Je(t,e,r,n=!1){const o=e=>{w(t)||r(e)};t[n?"once":"on"](e,o),b(t).add(()=>{t.off(e,o)})}function Qe(t,e,r){for(const[n,o]of e){if(w(t)||r&&!r())return;t[n].show=o}}function tr(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=Zt(t),c=0;return{reset(){c=0,a?.dispose(),D(i,"art-error")},loadStart(){D(i,"art-error")},schedule(l){(async l=>{if(w(t))return;const d=Zt(t);if(d!==s&&(s=d,c=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!w(t)&&!u.closed&&d===Zt(t),f=c{console.warn("ArtPlayer reconnect failed:",t)})}}}const er=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],rr=(()=>{if("undefined"===typeof document)return!1;const t=er[0],e={};for(const r of er){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),nr={change:rr.fullscreenchange,error:rr.fullscreenerror},or={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{or.off("change",o),r()};or.on("change",o);const i=t[rr.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!or.isFullscreen)return void t();const r=()=>{or.off("change",r),t()};or.on("change",r);const n=document[rr.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>or.isFullscreen?or.exit():or.request(t,e),onchange(t){or.on("change",t)},onerror(t){or.on("error",t)},on(t,e){const r=nr[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=nr[t];r&&document.removeEventListener(r,e,!1)},raw:rr};function ir(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(or,{isFullscreen:{get:()=>Boolean(document[rr.fullscreenElement])},element:{enumerable:!0,get:()=>document[rr.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[rr.fullscreenEnabled])}});const ar=new WeakMap;function sr(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function cr(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=ar.get(t);if(!n){n=new WeakMap,ar.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),sr(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),sr(i))}function lr(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,c=!1,l=!1,d=!1,u=!1,p=!1;const f=new Promise((t,e)=>{a=t,s=e});function h(t=!1,e){if(!c){c=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{c||(c=!0,l=!0,a(),d&&!u&&r&&cr(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&h()};if(ht(i,t.document,t.changeEvent,m),ht(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&h(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){ar.get(t.document)?.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,l&&!u&&r&&cr(t),u?Promise.resolve(e).then(()=>{l?n():h()},t=>h(!0,t)).catch(()=>{}):p?h(!0,new Error("Fullscreen request failed")):m()}catch(g){h(!0,g)}return{promise:f,cancel:()=>i.dispose()}}function dr(t,e){const r=b(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),c=0,l=s,d=!1,u=!1,p=!1;function f(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{c+=1,l=!1,n.classList.remove("art-fullscreen"),f()}),ht(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return ar.get(t.document)?.has(t.target)??!1}(e))return;if(r&&u)return void f();if(r===s||w(t))return;s=r;const o=c,a=()=>w(t)||i()!==r||o!==c&&l!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),ht(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!w(t)&&t.emit("fullscreenError",r)}),{get:()=>!w(t)&&i(),set(n){if(w(t))return Promise.resolve();const o=++c;if(l=Boolean(n),l?u=!1:d&&(u=!0),a?.cancel(),a=void 0,d=!1,!l&&!i())return Promise.resolve();p=!0,d=l;const s=lr(e,r,l,()=>{!w(t)&&l||f()},()=>!i());p=!1,c===o?a=s:s.cancel();const h=s.promise.catch(e=>{throw w(t)||c!==o||(t.notice.show=e),e}).finally(()=>{c===o&&(a=void 0,d=!1)});return h.catch(()=>{}),h}}}const ur=new WeakSet;function pr(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function fr(t){ur.delete(t),t.removeEventListener("webkitbeginfullscreen",hr),t.removeEventListener("webkitpresentationmodechanged",hr)}function hr(t){if(ur.has(this)&&pr(this,"webkitbeginfullscreen"===t.type)){fr(this);try{this.webkitExitFullscreen?.()}catch{}}}function mr(t){ur.add(t),t.addEventListener("webkitbeginfullscreen",hr),t.addEventListener("webkitpresentationmodechanged",hr)}function gr(t){const{$video:e}=t.template,r=b(t).child();let n=!1,o=pr(e),i=o,a=!1,s=0;const c=()=>pr(e,n);function l(r){if(w(t)||(l=e,ur.has(l)))return;var l;"boolean"===typeof r&&(n=r);const d=c();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>w(t)||c()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{s++,i=!1,a&&mr(e),c()&&e.webkitExitFullscreen?.()}),ht(r,e,"webkitbeginfullscreen",()=>l(!0)),ht(r,e,"webkitendfullscreen",()=>l(!1)),ht(r,e,"webkitpresentationmodechanged",()=>l());const d=()=>l();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!w(t)&&c(),set(r){if(w(t))return;const n=++s;if(i=Boolean(r),r){if(fr(e),t.state="fullscreen",w(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,mr(e)),c()&&e.webkitExitFullscreen()}}}function vr(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function yr({node:t,parent:e,next:r}){if(!e)return void t.parentNode?.removeChild(t);const n=r?.parentNode===e?r:null;t.parentNode===e&&t.nextSibling===n||e.insertBefore(t,n)}function br(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function wr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function xr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const c=t.icons.play,l=t.icons.pause;if(o.closed)return;i.append(c,l),s.append(e,i),wt(o,e,()=>e.click(),r),wt(o,i,()=>(t.playing?l:c).click(),r);const d=t.i18n.get("Close");if(o.closed||w(t))return;e.setAttribute("aria-label",d);const u=t.i18n.get("Mini Player");if(o.closed||w(t))return;s.setAttribute("role","group"),s.setAttribute("aria-label",u),ht(o,s,"keydown",t=>{const e=t;r()&&bt(e)&&!e.defaultPrevented&&"Escape"===e.key&&(yt(e),n())}),ht(o,e,"click",n),ht(o,c,"click",()=>{G(t.play())}),ht(o,l,"click",()=>{t.pause()});const p=()=>{if(o.closed)return;const e=t.i18n.get(t.playing?"Pause":"Play");o.closed||w(t)||(i.setAttribute("aria-label",e),c.style.display=t.playing?"none":"flex",l.style.display=t.playing?"flex":"none")};p();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,p),o.add(()=>{t.off(r,p)});const f=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};ht(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const c=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},l=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=br(i.left,i.top,wr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",c),r.add(()=>{t.off("document:mousemove",c)}),t.on("document:mouseup",l),r.add(()=>{t.off("document:mouseup",l)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:f,fresh:!0,focus:()=>e.focus({preventScroll:!0})}}catch(c){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,c}}function kr(t){const{$player:e,$video:r}=t.template,n=b(t).child();let o,i,a=0,s=!1,c=!1;const l=()=>!w(t)&&e.classList.contains("art-mini"),d=function(t){const e=t.template.$player;let r;return{entering(){const n=e.ownerDocument,o=n.activeElement,i=o&&e.contains(o);t.template.$mini?.contains(o)||(r=i?Ht(o):void 0);const a=i&&e.classList.contains("art-keyboard-focus");return e=>{!a||w(t)||n.activeElement!==o&&n.activeElement!==n.body||e?.()}},leaving(n){const o=e.ownerDocument,i=n?.contains(o.activeElement);return()=>{if(!i||w(t)||o.activeElement!==o.body&&!n?.contains(o.activeElement))return;const e=r&&o.defaultView?.getComputedStyle(r).visibility;r?.isConnected&&r.getClientRects().length&&"hidden"!==e&&"collapse"!==e&&"true"!==r.getAttribute("aria-disabled")&&!r.matches(":disabled")&&!r.closest("[inert]")?r.focus({preventScroll:!0}):Et(t)}}}}(t);function u(){if(i){const e=i,r=a;i=void 0;try{yr(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(w(t))return;const r=++a;c=!1;const n=d.leaving(t.template.$mini);u(),w(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",n(),w(t)||r!==a||t.emit("mini",!1)))}function f(){if(w(t))return;const h=++a;if(s)return void(c=!0);const m=d.entering();if(t.state="mini",!w(t)&&h===a){i??(i=vr(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=xr(t,n,l,p)}finally{s=!1}}if(c)return c=!1,void f();if(!o||w(t))return;if(h!==a)return void(l()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),w(t)||h!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:{...br(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,wr(o.element));if(w(t)||h!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),w(t)||h!==a)return;t.storage.set("left",i.left)}w(t)||h!==a||m(o.focus),w(t)||h!==a||t.emit("mini",!0)}catch(g){const r=c;throw c=!1,w(t)||h!==a&&!r||(u(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),g}}}return n.add(()=>{a++;try{u()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:l,set(t){t?f():p()}}}const $r=new WeakSet,Er=t=>"picture-in-picture"===t.webkitPresentationMode;function Ar(t){$r.delete(t),t.removeEventListener("webkitpresentationmodechanged",Cr),t.removeEventListener("enterpictureinpicture",Cr)}function Cr(){if($r.has(this)&&Er(this)){Ar(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function Sr(t){$r.add(t),t.addEventListener("webkitpresentationmodechanged",Cr),t.addEventListener("enterpictureinpicture",Cr)}function Tr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function Lr(t,e,r){return new Promise((n,o)=>{if(w(t)||e===t.url)return void n();const i=Qt(t),a=i.scope.child();let s=!1;const c=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{c()});const l=()=>!s&&i.active(),d=t=>c(!0,t);i.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!l())return;const u=a.child();let p=!1,f=!1,h=!1;const m=le(t,r,l),g=async()=>{if(t.aspectRatio=o,l()){if(n)try{await t.play()}catch{}l()&&(t.notice.show="",c())}},v=()=>{if(l()&&!f&&p)try{if(t.template?.$video?.seeking)return;if(!l())return;if(h||(h=!0,t.playbackRate=s),!m.ready()||!l()||f)return;f=!0,u.dispose(),g().catch(d)}catch(e){d(e)}},y={"video:error":d,"video:loadedmetadata":()=>{if(l())try{m.restore()}catch(t){d(t)}},"video:canplay":()=>{p=!0,v()},"video:seeked":v,seek:m.manual},b=a.child(),w=[],x=Object.keys(y);for(const e of x)Tr(b,t,e,t=>{i.acceptingEvents&&w.push([e,t])},!1);if(ee(t,i,e),!l())return;if(t.notice.show="",!l())return;const k=()=>{if(b.dispose(),!e)return void c();const r={};for(const e of x)r[e]=Tr(u,t,e,y[e],"video:seeked"!==e);for(const[t,e]of w){if(!l()||u.closed)break;r[t](e)}w.length=0};i.assigned?k():i.onAssigned=k}catch(u){d(u)}})}function Pr(t,e){const{number:r,column:n,width:o,height:i,scale:a}=t,{imageWidth:s,videoWidth:c,videoHeight:l,progressWidth:d,position:u}=e,p=Number(n),f=Number(o)*Number(a)||s/p,h=Number(i)*Number(a)||f/(c/l),m=Math.floor(u/(d/Number(r)));return{height:`${h}px`,width:`${f}px`,backgroundPosition:`-${m%p*f}px -${Math.floor(m/p)*h}px`,left:u<=f/2?0:u>d-f/2?d-f+"px":u-f/2+"px"}}function Mr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(w(t))return;const o=function(t){const e=Gt.get(t);return Gt.delete(t),e||Qt(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await gt(o.scope)&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||K(n),s=e.customType[a];if(a&&s){if(!(await gt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const c=o.scope.child();let l=!1,d=!1;Tr(c,t,"video:canplay",()=>{l=!d}),Tr(c,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>re(o,t))}else{if(!o.active())return;r.src=n}}finally{c.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};l?e():d||Tr(o.scope,t,"video:canplay",e)}}catch(i){re(o,i)}finally{te(o)}}})}const zr=[function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){const n=e;if(void 0===r)return n[t];n[t]=r}})},function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=Jt(t),s=await i.play();if(!a())return s;const c=e.get("Play");if(!a())return s;if(r.show=c,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})},function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${tt(t.currentTime)} / ${tt(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;it(t,"forward",{set(e){r.seek=t.currentTime+e}}),it(t,"backward",{set(e){r.seek=t.currentTime-e}})},function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=J(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),it(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})},function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){se.set(t,ce(t)+1)}(t),e.currentTime=J(n,0,t.duration))}})},function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})},function(t){const e=e=>Lr(t,e,0);it(t,"switchQuality",{value:e=>Lr(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})},function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;it(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!w(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ze({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(w(t))return;"width"===r?.axis?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,w(t)||t.emit("aspectRatio",i)}}})},function(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=Jt(t);return new Promise((a,s)=>{const c=r=>{try{!w(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,c):a(n.toDataURL("image/png"))}catch(l){c(l)}})}it(t,"getDataURL",{value:()=>o(!1)}),it(t,"getBlobUrl",{value:()=>o(!0)}),it(t,"screenshot",{value:async e=>{const n=Jt(t),o=await t.getDataURL();if(!w(t)&&n()){const i=e||`artplayer_${tt(r.currentTime)}`;!w(t)&&n()&&Z(o,`${i}.png`),!w(t)&&n()&&t.emit("screenshot",o)}return o}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(w(t))return;const i=function(t){const e=or.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>ir(t,e.requestFullscreen,void 0),exit:()=>ir(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",dr(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",gr(t)):it(t,"fullscreen",{get:()=>!1,set(){w(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",ct(t,"fullscreen"))};t.once("video:loadedmetadata",i),b(t).add(()=>{t.off("video:loadedmetadata",i)})},function(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(yr(t.placement),r()))}return b(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(i){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(a){throw new h([i,a])}throw i}}),i=>{if(w(t))return;const a=++n,s=()=>a===n&&!w(t),c=function(t){const e=t.ownerDocument?.activeElement,r=e&&t.contains(e);return()=>{r&&e.isConnected&&t.contains(e)&&e.ownerDocument.activeElement===e.ownerDocument.body&&e.focus({preventScroll:!0})}}(e);if(i){r||(r={placement:vr(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0,c()),l}if(!s())return;if(c(),!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;if(c(),!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);it(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})},function(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?it(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=b(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,c=!1,l=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function u(e,r,n){e.then(()=>{!r||!w(t)&&a||d()},e=>{w(t)||l!==n||(t.notice.show=e)}).finally(()=>{l===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{l++,a=!1,d()}),ht(n,e,"enterpictureinpicture",()=>{if(c)return void d();if(!o()||i)return;const e=l;t.state="pip",!w(t)&&e===l&&o()&&(i=!0,t.emit("pip",!0))}),ht(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!w(t)&&o()?e:null,set(n){if(w(t))return;const i=++l;if(a=Boolean(n),a?c=!1:s&&(c=!0),s=!1,a){if(t.state="pip",w(t)||l!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw l===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=b(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(w(t)||$r.has(e))return;const s=Er(e);if(s&&(o=!1),s===n&&!r)return;const c=i;s&&(t.state="pip"),w(t)||i!==c||Er(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&Sr(e),Er(e)&&e.webkitSetPresentationMode("inline")});for(const c of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])ht(r,e,c,()=>s());return{get:()=>!w(t)&&Er(e),set(r){if(w(t))return;const n=++i,c=a;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(Ar(e),t.state="pip",w(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(l){throw n===i&&(o=!1),l}}else o&&(o=!1,Sr(e)),Er(e)&&e.webkitSetPresentationMode("inline");w(t)||n!==i||c!==a||Er(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){w(t)||(r.show=e.get("PIP Not Supported"))}})},function(t){const{$video:e}=t.template,r=t;it(t,"loaded",{get:()=>r.loadedTime/e.duration}),it(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})},function(t){it(t,"played",{get:()=>t.currentTime/t.duration})},function(t){const{$video:e}=t.template;it(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})},function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(w(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Ke(o))return;const i=M(e),a=Ze(i,o.width/o.height);a&&!w(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})},function(t){const e=t;it(t,"rect",{get:()=>M(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}it(t,"x",{get:()=>e.left+window.pageXOffset}),it(t,"y",{get:()=>e.top+window.pageYOffset})},function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){w(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,w(t)||t.emit("flip",o))}})},function(t){it(t,"mini",kr(t))},function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){H(e,"backgroundImage",`url(${t})`)}})},function(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(w(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Ke(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||w(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})},function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})},function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})},function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})},function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];it(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;nn.$track?.offset||0,set(o){const{cues:i}=t.subtitle;if(!n.$track||0===i.length)return;const a=J(o,-10,10);n.$track.offset=a;for(let e=0;e{if(!w(t))switch(e.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,w(t)||it(t,"airplay",{value(){if(!w(t))if(i){const e=o.webkitShowPlaybackTargetPicker;if(w(t))return;Reflect.apply(e,o,[]),w(t)||t.emit("airplay")}else{const n=e.get("AirPlay Not Available");w(t)||(r.show=n)}}}))},function(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:i?.html||"",selector:e,async onSelect(e,r,i){const a=function(t){return t&&fe.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!w(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!w(t)&&a()&&(n.show=r)}return e.html}})}})},function(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,s=b(t).child(),c=!1;function l(){const e=s;s=b(t).child(),o=void 0,c=!1,a=void 0,e.dispose()}function d(){const i=a,c=s;if(!i||!o)return;const l=()=>!w(t)&&!c.closed&&s===c&&a===i&&i.sourceActive()&&t.controls?.thumbnails===i.element;if(!l())return;const d=r.clientWidth*i.percentage;if(!(d>0&&d{const f=t.controls?.thumbnails,{url:h,scale:m}=e.thumbnails;if(!w(t)&&f&&h&&("hover"===r||"played"===r&&p&&u)){if(i!==f){const t=E(f);if(t.closed)return;i=f,t.add(()=>{i===f&&(i=void 0,l())})}if(a={percentage:n,element:f,sourceActive:Jt(t)},o)d();else if(!c){const t=s;c=!0,function(t,e,r){return q(t,e,r)}(h,m,t).then(e=>{s!==t||t.closed||(c=!1,o=e,d())}).catch(e=>{s!==t||t.closed||(c=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{w(t)||!e.url||t.option.isLive||w(t)||(t.option.thumbnails=e,l())}})},function(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{w(t)||t.emit(`video:${e.type}`,e)})}(t);const e=tr(t);!function(t,e){Je(t,"video:canplay",()=>{e.reset(),Qe(t,[["loading",!1]])}),Je(t,"video:canplay",()=>{Qe(t,[["loading",!1],["controls",!0],["mask",!0]]),w(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Je(t,"video:ended",()=>{if(e.loop){const e=Jt(t);if(t.seek=0,w(t)||!e())return;G(t.play()),e()&&Qe(t,[["controls",!1],["mask",!1]],e)}else Qe(t,[["controls",!0],["mask",!0]])})}(t),Je(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Je(t,"video:loadedmetadata",()=>{t.emit("resize"),u&&Qe(t,[["loading",!1],["controls",!0],["mask",!0]])}),Je(t,"video:loadstart",()=>{e.loadStart(),Qe(t,[["loading",!0],["mask",!1],["controls",!0]])}),Je(t,"video:pause",()=>{Qe(t,[["controls",!0],["mask",!0]])}),Je(t,"video:play",()=>{Qe(t,[["mask",!1]]),w(t)||H(r,"display","none")}),Je(t,"video:playing",()=>Qe(t,[["mask",!1]])),Je(t,"video:progress",()=>{t.playing&&Qe(t,[["loading",!1]])}),Je(t,"video:seeked",()=>Qe(t,[["loading",!1],["mask",!0]])),Je(t,"video:seeking",()=>Qe(t,[["loading",!0],["mask",!1]])),Je(t,"video:timeupdate",()=>Qe(t,[["mask",!1]])),Je(t,"video:waiting",()=>Qe(t,[["loading",!0],["mask",!1]]))}(t,e)},function(t){if(w(t))return;const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const s in e.moreVideoAttr){if(w(t))return;const r=e.moreVideoAttr[s];if(w(t))return;t.attr(s,r)}if(w(t))return;if(e.muted){const r=e.muted;if(w(t))return;t.muted=r}if(w(t))return;if(e.volume){const r=J(e.volume,0,1);if(w(t))return;n.volume=r}if(w(t))return;const i=r.get("volume");if(w(t))return;if("number"===typeof i&&(n.volume=J(i,0,1)),w(t))return;if(e.poster){const r=`url(${e.poster})`;if(w(t))return;H(o,"backgroundImage",r)}if(w(t))return;if(e.autoplay){const r=e.autoplay;if(w(t))return;n.autoplay=r}if(w(t))return;if(e.playsInline){if(w(t))return;if(n.playsInline=!0,w(t))return;n["webkit-playsinline"]=!0}if(w(t))return;if(e.theme){const r=e.cssVar,n=e.theme;if(w(t))return;r["--art-theme"]=n}for(const s in e.cssVar){if(w(t))return;const r=e.cssVar[s];if(w(t))return;t.cssVar(s,r)}if(w(t))return;const a=e.url;w(t)||(t.url=a)}];class Rr{constructor(t){if(!w(t)){Mr(t);for(const e of zr){if(w(t))return;e(t)}}}}const Or=new WeakMap,Dr="art-auto-orientation-fullscreen";function Ir(t){if(Or.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const Nr="art-auto-orientation",_r=["width","height","transform-origin","transform"];function Wr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Ke(t)&&Ke(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=b(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(Nr);r.classList.remove(Nr),n&&(t.isRotate=!1,w(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=z();if(w(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=_r.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(Nr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{w(t)||(r?o?s(!1):e()&&(i(),i=mt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(Dr),t&&(t.cancelled=!0,Ir(t),t.settled&&Or.get(t.orientation)===t&&Or.delete(t.orientation))}return b(t).add(o),i=>{if(w(t))return;if(!i)return void o();if(n&&!n.cancelled&&Or.get(n.orientation)===n)return;const a=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof a?.lock||"function"!==typeof a.unlock||!e())return;const s={orientation:a,cancelled:!1,settled:!1};n=s,Or.set(a,s);const c=()=>!w(t)&&!s.cancelled&&n===s&&Or.get(a)===s,l=e=>{s.settled=!0;const o=c();Or.get(a)===s&&Or.delete(a),n===s&&(n=void 0),o&&(r.classList.remove(Dr),t.notice.show=e)};try{const t=a.lock(a.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,c()?r.classList.add(Dr):(Ir(s),Or.get(a)===s&&Or.delete(a))}).catch(l)}catch(d){l(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),b(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Fr(t){return t.get("times")||{}}function Vr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||w(t))return()=>{};const s=kt(".art-auto-playback-last",a),c=kt(".art-auto-playback-jump",a),l=kt(".art-auto-playback-close",a);xt(l,r.close);const d=E(a);let u,p=0;const f=()=>{const r=++p;if(u?.dispose(),d.closed||w(t)||p!==r)return;const f=d.child();u=f;const h=()=>u===f&&!f.closed&&!w(t);f.add(()=>{u===f&&(u=void 0,H(a,"display","none"))});const m=Zt(t).add(()=>{f.dispose()});f.add(()=>{m()});const g=Fr(n)[t.option.id||t.option.url];if(!h())return;if(H(a,"display","none"),!h()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!h())return;if(H(a,"display","flex"),!h())return;const v=`${e.get("Last Seen")} ${tt(g)}`;if(!h())return;if(s.textContent=v,!h())return;const y=e.get("Jump Play");if(!h())return;if(c.textContent=y,!h())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{h()&&r()});f.add(()=>{t.events.remove(n)})};if(b(l,()=>{H(a,"display","none")}),!h())return;if(b(c,()=>{t.seek=g,h()&&(G(t.play()),h()&&(H(i,"display","none"),h()&&H(a,"display","none")))}),!h())return;let x=()=>{},k=!1;const $=()=>{!k&&h()&&(k=!0,x(),mt(f,()=>{h()&&H(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",$),x=f.add(()=>{t.off("video:timeupdate",$)}),k&&x()};return()=>{C(t,a,"ready",f),C(t,a,"restart",f)}}(t);return function(t){const{storage:e,constructor:r}=t;Se(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Fr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;w(t)||(o.length>i&&delete n[o[0]],n[a]=s,w(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Fr(e)},clear:()=>e.del("times"),delete(t){const r=Fr(e);return delete r[t],e.set("times",r),r}}}function Yr(t){let e,r=0;return{start:n=>{const o=++r;if(e?.scope.dispose(),o!==r||w(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:Zt(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{e?.active||D(t.template.$player,"art-fast-forward")}}),mt(i.scope,()=>{if(e!==i||w(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||w(t))return;t.playbackRate=r,e!==i||i.scope.closed||w(t)||O(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,e?.scope.dispose()}}}function Br(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Yr(t),i=Se(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return I(r,"art-fast-forward")}}}function Hr(t,e,r,n){let o;const i=()=>!r.closed&&!w(t),a=t.i18n.get("Lock");if(!i())return()=>{};e.setAttribute("aria-label",a),wt(r,e),ht(r,e,"keydown",t=>{const r=t;i()&&n()&&bt(r)&&!r.defaultPrevented&&"Escape"===r.key&&(yt(r),e.click())});const s=n=>{if(i())if(e.setAttribute("aria-pressed",String(n)),n&&!o){const{$player:n,$bottom:a}=t.template,s=a.contains(a.ownerDocument.activeElement)&&n.classList.contains("art-keyboard-focus");o=r.child(),function(t,e){const r=new Map,n=e.hasAttribute("inert"),o=e.getAttribute("aria-hidden"),i=(t,e)=>{"-1"===t.getAttribute("tabindex")&&(null===e?t.removeAttribute("tabindex"):t.setAttribute("tabindex",e))};if(t.add(()=>{for(const[t,e]of r)i(t,e);r.clear(),n||""!==e.getAttribute("inert")||e.removeAttribute("inert"),"true"===e.getAttribute("aria-hidden")&&(null===o?e.removeAttribute("aria-hidden"):e.setAttribute("aria-hidden",o))}),t.closed)return;n||e.setAttribute("inert",""),e.setAttribute("aria-hidden","true");const a=()=>{if(!t.closed){for(const[t,n]of r)e.contains(t)||(i(t,n),r.delete(t));for(const t of e.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]"))r.has(t)||(r.set(t,t.getAttribute("tabindex")),t.setAttribute("tabindex","-1"))}};if(a(),"undefined"!==typeof MutationObserver){const r=new MutationObserver(a);r.observe(e,{childList:!0,subtree:!0}),t.add(()=>{r.disconnect()})}}(o,a),i()&&s&&e.focus({preventScroll:!0})}else if(!n&&o){const t=o;o=void 0,t.dispose()}};return s(n()),s}function jr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return I(n,"art-lock")}function i(){w(t)||(O(n,"art-lock"),w(t)||(t.isLock=!0,w(t)||t.emit("lock",!0)))}function a(){w(t)||(D(n,"art-lock"),w(t)||(t.isLock=!1,w(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=E(e);if(n.closed||w(t))return;const i=xt(e,r.lock);if(n.closed||w(t))return;const a=xt(e,r.unlock);if(n.closed||w(t))return;const s=Hr(t,e,n,o);n.closed||w(t)||(o()?(H(i,"display","inline-flex"),n.closed||w(t)||H(a,"display","none")):H(i,"display","none"),C(t,e,"lock",e=>{w(t)||(H(i,"display",e?"inline-flex":"none"),n.closed||w(t)||H(a,"display",e?"none":"inline-flex"),n.closed||w(t)||s(e))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function qr(t){return Se(t)("control",e=>{e?D(t.template.$player,"art-mini-progress-bar"):O(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Ur{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){w(t.art)||!e.miniProgressBar||e.isLive||t.add(qr),!w(t.art)&&e.lock&&u&&t.add(jr),w(t.art)||!e.autoPlayback||e.isLive||t.add(Vr),!w(t.art)&&e.autoOrientation&&u&&t.add(Wr),!w(t.art)&&e.fastForward&&u&&!e.isLive&&t.add(Br)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!w(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(w(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(w(t.art))return t;let o=n;const i=st(t,o);if(w(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return w(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),w(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const Xr=new WeakMap;function Gr(t){return!t.closed&&!Xr.get(t)}function Kr(t){Xr.set(t,(Xr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Xr.get(t)||1)-1;r?Xr.set(t,r):Xr.delete(t)}}const Zr=new WeakMap,Jr=new WeakMap,Qr=["$parent","$parents","$option","$events","$formatted"];function tn(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=Zr.get(r);if(!t||!t.owner.active||t.owner.scope?.closed||!t.option.includes(r))return!1;if(!t.parent)return t.owner.root===t.option;if(Zr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function en(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function rn(t){const e=Zr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function nn(t,e){for(let r=0;r{l&&l!==r&&l.dispose()},()=>un(t,o)])try{e()}catch(d){d instanceof h?c.push(...d.errors):c.push(d)}if(r.closed||w(t)||(o.push(...i.splice(0)),dn.set(r,o),cn.set(e,r),ln.set(e,n)),a(),c.length)throw new h(c)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function gn(t,e,r,n,o,i){const a=i||fn(e);if(!Gr(a)||w(t))return;const s=t.proxy(r,n,e=>{if(Gr(a)&&!w(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Gr(a)||w(t)?t.events.remove(s):(rn(e).events.push(s),i&&i!==cn.get(e)&&i.add(()=>{const r=rn(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function vn(t,e,r,n){const o=fn(e);if(!Gr(o)||w(t))return;const i=(...e)=>{if(Gr(o)&&!w(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function yn(t){const e=t.ownerDocument.defaultView?.getComputedStyle(t).visibility;return t.isConnected&&!t.matches(":disabled")&&!t.closest("[inert]")&&"true"!==t.getAttribute("aria-disabled")&&t.getClientRects().length>0&&"hidden"!==e&&"collapse"!==e}function bn(t){return Array.from(t.querySelectorAll('[tabindex="0"],button,input,select,textarea,a[href],[contenteditable]')).filter(t=>"-1"!==t.getAttribute("tabindex")&&yn(t))}function wn(t,e,r=!1){if(!t.show||w(t.art)||!t.active)return;const n=t.cache.get(t.active);if(!n||!Gr(an(n)))return;const o=bn(n),i=n.querySelector(".art-setting-item.art-current"),a=o.find(t=>e===t||e?.contains(t))||(r?o[o.length-1]:o.find(t=>i?.contains(t))||o.find(t=>!t.classList.contains("art-setting-item-back"))||o[0]);a?.focus({preventScroll:!0}),w(t.art)||a?.scrollIntoView({block:"nearest",inline:"nearest"})}function xn(t){const e=t.$parent.ownerDocument,r=e.activeElement,n=t.$parent.contains(r);return o=>{n&&!w(t.art)&&(e.activeElement===e.body||e.activeElement===r&&!r?.getClientRects().length)&&wn(t,o)}}function kn(t){const{art:e}=t,r=b(e).child();if(r.closed)return;const n=()=>t.$parent.ownerDocument;let o=!1;const i=()=>{t.show=!1,r.closed||w(e)||t.render()},a=i=>{r.closed||w(e)||(i?n().activeElement===e.controls.setting&&e.template.$player.classList.contains("art-keyboard-focus")&&wn(t,void 0,o):t.$parent.contains(n().activeElement)&&function(t){const{art:e,$parent:r}=t,n=e.template.$player,o=r.ownerDocument,i=e.controls.setting;!w(e)&&r.contains(o.activeElement)&&(i&&n.contains(i)&&yn(i)&&i.focus({preventScroll:!0}),(o.activeElement===o.body||r.contains(o.activeElement))&&Et(e))}(t))};e.on("setting",a),r.add(()=>{e.off("setting",a)}),ht(r,e.template.$player,"keydown",r=>{const n=r;if(!bt(n)||n.defaultPrevented||w(e))return;const a=n.target;if(a===e.controls.setting){if("ArrowDown"===n.key||"ArrowUp"===n.key)if(yt(n),t.show)wn(t,void 0,"ArrowUp"===n.key);else{o="ArrowUp"===n.key;try{t.show=!0}finally{o=!1}}else"Escape"===n.key&&t.show&&(yt(n),i());return}if(!t.show||!t.$parent.contains(a))return;if("Escape"===n.key)return yt(n),void i();const s=a.closest(".art-setting-item");if(!s||a!==s&&!a.matches('button,a[href],[role="button"]'))return;const c=t.active&&t.cache.get(t.active);if(!c)return;const l=t.active?.find(t=>t.$item===s);if(!Gr(an(c))||l&&!Gr(fn(l)))return void(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End"].includes(n.key)&&yt(n));const d=bn(c),u=d.indexOf(a);if(u<0)return;let p;switch(n.key){case"ArrowDown":p=Math.min(u+1,d.length-1);break;case"ArrowUp":p=Math.max(u-1,0);break;case"Home":p=0;break;case"End":p=d.length-1;break;case"ArrowLeft":{const t=c.querySelector(".art-setting-item-back");return yt(n),void t?.click()}case"ArrowRight":return yt(n),void(l?.selector?.length&&a.click());default:return}yt(n),void 0!==p&&wn(t,d[p])});let s=!1;ht(r,t.$parent,"focusout",o=>{const a=o.relatedTarget;a&&(t.$parent.contains(a)||a===e.controls.setting)||s||(s=!0,mt(r,()=>{s=!1,r.closed||w(e)||!t.show||t.$parent.contains(n().activeElement)||n().activeElement===e.controls.setting||i()},0))})}function $n(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:i},template:{$player:a,$setting:s,$bottom:c}}=e;if(!n.setting||!t.show||!r)return;const l=a.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),p=l.width/a.offsetWidth||1,f=(d.left-l.left+d.width/2)/p-a.clientLeft,h=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:c}=t,l=Math.min(Math.max(0,c),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*l));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-l)),left:Math.max(l,Math.min(a-d/2,e-l-d))}}({containerWidth:a.clientWidth,containerHeight:a.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:i,controlCenter:f,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(c).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||u||(f+h.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const En=new WeakMap;function An(t){En.delete(t)}const Cn=new WeakMap;function Sn(t,e){e?Cn.set(t,e):Cn.delete(t)}function Tn(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=Cn.get(t),o=n?.();for(const i of["html","icon","tooltip"]){const t=e.get(i)?.value;t instanceof Node&&r.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{for(const r of Reflect.ownKeys(t))!e.has(r)&&Object.getOwnPropertyDescriptor(t,r)?.configurable&&Reflect.deleteProperty(t,r);for(const[r,n]of e)Object.defineProperty(t,r,n);o?.(),Sn(t,n);for(const{node:t,parent:e,next:n}of r)e?e.insertBefore(t,n?.parentNode===e?n:null):t.parentNode?.removeChild(t)}}function Ln(t){const e=t.$item?.querySelector(".art-setting-range");e&&e.setAttribute("aria-label",t.$html?.textContent||"")}const Pn=new WeakMap;async function Mn(t,e,r,n,o,i,a,s){try{const c=fn(e),l=fn(i),d=(Pn.get(i)||0)+1;Pn.set(i,d);const u=()=>Gr(c)&&Gr(l)&&!w(t.art)&&Pn.get(i)===d;if(s?.(),!u())return;const p=await o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(c){console.warn("ArtPlayer setting callback failed:",c)}}function zn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const Rn=new WeakMap;function On(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof h?e.push(...r.errors):e.push(r)}if(e.length)throw new h(e)}function Dn(t){Rn.get(t)?.()}function In(t,e){const r=t.find(e.name);if(w(t.art))return r||e;if(!r)return t.add(e);const n=xn(t);An(r),Dn(r);const o=Tn(r),i=r.$item,a=i?.parentNode,s=i?.nextSibling,c=i?zn(i):void 0,l=t.active,d=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),u=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=mn(t.art,e);r&&i.push(r)}for(const t of n)a.push(Kr(an(t)))}catch(c){try{On([...i.reverse().map(t=>t.resume),...a])}catch(l){console.warn("ArtPlayer setting restore failed:",l)}throw c}let s=!0;return{items:r,resume(){s&&(s=!1,On([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,On([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>sn(t)),...a]))}}}(t,r);let p=!0,f=!1;const h=()=>{if(!p)return;p=!1;for(const t of u.items)Rn.get(t)===h&&Rn.delete(t);if(w(t.art))return void u.dispose();const e=r.$item;try{On([u.resume,()=>{e&&e!==i&&e.remove()},o,()=>c?.(),()=>{a&&i&&a.insertBefore(i,s?.parentNode===a?s:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&W(t.cache.get(l),"art-current");for(const[e,r,n]of d)t.$parent.style.setProperty(e,r,n)}}]),n(i)}catch(m){console.warn("ArtPlayer setting restore failed:",m)}},m=()=>p&&!w(t.art)&&Rn.get(r)===h;for(const y of u.items)Rn.set(y,h);const g=b(t.art).add(()=>{p=!1;for(const t of u.items)Rn.get(t)===h&&Rn.delete(t);u.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!o?.enumerable||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,m),!m())return r;if(t.format(),!m())return r;if(t.createItem(r,!0),!m())return r;if(f=!0,t.render(),!m())return r;p=!1;for(const t of u.items)Rn.get(t)===h&&Rn.delete(t);return u.dispose(),n(r.$item),r}catch(v){throw m()&&h(),v}finally{g()}}const Nn=new WeakMap;function _n(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(n){r.innerHTML="",N(r,n),"html"===e&&Ln(t)}})}function Wn(t,e,r=!1){const n=function(t){const e=Rn.get(t);return()=>!e||Rn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),i=e.$item;let a="selector";st(e,"switch")&&(a="switch"),st(e,"range")&&(a="range"),st(e,"onClick")&&(a="button");const{icons:s,constructor:c}=t.art;if(!n())return;const l=function(t,e,r=b(t)){const n=cn.get(e);(!n||Gr(n)||n.closed)&&hn(t,e);const o=r.child();return cn.set(e,o),ln.set(e,r),dn.set(o,rn(e).events),o.add(()=>{un(t,dn.get(o))}),o}(t.art,e,an(o)),d=()=>Gr(l)&&!w(t.art)&&n();if(!d())return;const u=document.createElement("div");try{if(Sn(e),O(u,"art-setting-item"),H(u,"height",`${c.SETTING_ITEM_HEIGHT}px`),u.dataset.name=e.name||"",u.dataset.value=String(e.value||""),!d())return;const n=xt(u,'
'),p=xt(u,'
'),f=document.createElement("div");switch(O(f,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;N(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;N(f,t)}else N(f,s.check)}if(N(n,f),!d())return;_n(e,"icon",f);const h=document.createElement("div");O(h,"art-setting-item-left-text");const m=e.html||"";if(!d())return;N(h,m),N(n,h),_n(e,"html",h);const g=document.createElement("div");O(g,"art-setting-item-right-tooltip");const v=e.tooltip||"";if(!d())return;switch(N(g,v),N(p,g),_n(e,"tooltip",g),a){case"switch":{const t=document.createElement("div");O(t,"art-setting-item-right-icon");const r=xt(t,s.switchOn),n=xt(t,s.switchOff),o=e.switch;if(!d())return;H(o?n:r,"display","none"),N(p,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;Sn(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,u.setAttribute("aria-checked",String(Boolean(t))),t?(H(n,"display","none"),H(r,"display",null)):(H(n,"display",null),H(r,"display","none"))}});break}case"range":{const t=document.createElement("div");O(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",N(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,i,String(t))}O(r,"art-setting-range"),N(p,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Sn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),it(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(e.selector?.length){const t=document.createElement("div");O(t,"art-setting-item-right-icon"),N(t,s.arrowRight),N(p,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=fn(e),a=(t,r,n)=>gn(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>Mn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>Mn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return Mn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&O(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>Mn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,u,a),!d())return;it(e,"$item",{configurable:!0,get:()=>u}),function(t,e,r,n,o){"range"!==n?r.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")||("switch"===n?(r.setAttribute("role","switch"),r.setAttribute("aria-checked",String(Boolean(e.switch))),r.setAttribute("aria-disabled",String(!e.onSwitch))):"selector"!==n||e.selector?.length||r.setAttribute("aria-current",String(Boolean(e.default))),wt(o,r,()=>r.click(),()=>Gr(o)&&!w(t.art))):Ln(e)}(t,e,u,a,l),r&&i?.parentNode?i.replaceWith(u):N(o,u),e.mounted&&d()&&mt(l,()=>{if(!w(t.art))try{const r=e.mounted?.call(t.art,u,e);Promise.resolve(r).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(r){console.warn("ArtPlayer setting mounted failed:",r)}},0)}catch(p){try{l.dispose()}catch(f){console.warn("ArtPlayer setting cleanup failed:",f)}throw u.remove(),p}}function Fn(t,e=t.option){if(w(t.art))return;const r=xn(t),n=t.cache.get(e);if(n&&!Gr(an(n)))return;const o=(Nn.get(t)||0)+1;Nn.set(t,o);const i=()=>Nn.get(t)===o&&!w(t.art),a=t.active,s=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),c=()=>{t.active=a,a&&t.cache.has(a)&&W(t.cache.get(a),"art-current");for(const[e,r,n]of s)t.$parent.style.setProperty(e,r,n)};if(t.active=e,n)try{W(n,"art-current"),t.resize()}catch(l){throw i()&&t.cache.get(e)===n&&!an(n).closed&&c(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=b(t.art).child();return on.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),o=()=>!n.closed&&!w(t.art)&&t.cache.get(e)===r,a=[];try{if(!o())return;O(r,"art-setting-panel"),r.setAttribute("role","group"),r.setAttribute("aria-label",e[0]?.$parent?.$html?.textContent||t.art.i18n.get("Settings")),N(t.$parent,r),W(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Jr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=b(e).child(),n=(t,n)=>{if(r.closed||w(e))return;const o=(...t)=>{if(!r.closed&&!w(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=L(r,e.controls.setting),o=L(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||w(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this)),kn(this)}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),vn(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),vn(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(Q(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),vn(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{vn(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){nn(e,t)}check(t){!function(t,e){e?.$parent&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.$item&&t.$item.setAttribute("aria-current",String(t.default)),t.default&&t.$item&&W(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Jr.get(t)||{active:!0},a=[],s=new Set,c=new Set(o),l=(t,e,r)=>{for(let n=0;nrn(t).parent},$parents:{get:()=>rn(t).parents},$option:{get:()=>rn(t).option},$events:{get:()=>rn(t).events},$formatted:{get:()=>!0}}),Zr.set(t,{parent:r,parents:n,option:o,events:a?.events||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return nn(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){$n(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&sn(n)}catch(i){r.push(i)}}try{hn(t.art,e)}catch(i){i instanceof h?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new h(r)}(this,t)}remove(t){const e=xn(this),r=this.find(t);X(r,`Can't find [${t}] in the [setting]`),this.traverse(t=>{An(t),Dn(t)},[r]);const n=r.$option.indexOf(r);r.$option.splice(n,1);const o=r.$item,i=[];for(const s of[()=>this.inactivate(r),()=>o?.remove(),()=>this.render()])try{s()}catch(a){a instanceof h?i.push(...a.errors):i.push(a)}if(i.length)throw new h(i);e()}update(t){return In(this,t)}add(t,e=this.option){if(w(this.art))return t;let r=!1;this.traverse(e=>{r||(r=e===t)});const n=e.length,o=r?void 0:function(t){const e={};En.set(t,e);const r=()=>En.get(t)===e;return{current:r,finish(){r()&&En.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(w(this.art)||o&&!o.current())throw a;if(e[n]===t&&e.splice(n,1),!r&&i){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw a}finally{o?.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");H(i,"height",`${o}px`),O(i,"art-setting-item"),O(i,"art-setting-item-back");const a=xt(i,'
'),s=document.createElement("div");O(s,"art-setting-item-left-icon"),N(s,n),N(a,s),N(a,e.$parent.html),gn(t.art,e.$parent,i,"click",()=>t.render(e.$parents),an(r));const c=an(r);i.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")||wt(c,i,()=>i.click(),()=>Gr(c)&&!w(t.art)),i.setAttribute("aria-label",`${t.art.i18n.get("Back")}: ${i.textContent?.trim()||""}`),N(r,i)}(this,t)}createItem(t,e=!1){Wn(this,t,e)}render(t=this.option){Fn(this,t)}}class Bn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch{return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch{this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch{delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch{this.settings={}}}}const Hn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:opacity var(--art-transition-duration) ease,transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel,.art-control-volume:focus-within .art-volume-panel{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:focus-within .art-mini-close,.art-mini-popup:hover .art-mini-state,.art-mini-popup:focus-within .art-mini-state{opacity:1}.art-mini-popup [role=button]:focus-visible{outline:2px solid #fff;outline-offset:-2px}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-layer-lock{display:flex}.art-video-player.art-lock:not(.art-control-show) .art-layer-lock{opacity:0;pointer-events:none}.art-video-player.art-lock:not(.art-control-show) .art-layer-lock:focus-within{opacity:1;pointer-events:auto}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:opacity var(--art-transition-duration) ease,transform var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover:not(.art-selector-dismissed) .art-selector-list,.art-control-selector.art-selector-open .art-selector-list{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}.art-video-player [tabindex]:focus-visible,.art-video-player input:focus-visible,.art-video-player button:focus-visible,.art-video-player a:focus-visible{outline:2px solid currentColor;outline-offset:-2px}.art-video-player.art-keyboard-focus :focus{outline:2px solid currentColor;outline-offset:-2px}.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom{opacity:1}.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-controls,.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-progress{transform:translateY(0)}';class jn{constructor(t){this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope)?.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}async run(t){if(this.active)try{return await Promise.race([t(),this.cancelled])}finally{this.cancel()}}}const qn=new WeakMap;function Un(t){return qn.get(t)}function Xn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const Gn=Wt;class Kn extends Gn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=b(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return qn.set(t,n),r.add(()=>{Xn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){return this.art.template.$video?.textTracks?.[0]}get activeCues(){return Array.from(this.textTrack?.activeCues||[])}get cues(){return Array.from(this.textTrack?.cues||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?j(r,t):H(r,t,e)}update(){!function(t){const e=Un(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?ot(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i={...o.subtitle,...e,url:t},a=Un(this),s=a.revision+1,c=await this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),c}createTrack(t,e){!function(t,e,r){const n=Un(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,c=s.parentNode,l=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const c=t.textTrack,l=c?i.proxy(c,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(l)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const f=n.track;n.track=u,t.destroyEvent=l,s.onload=null,s.onerror=null,p=!0;try{f?.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&Xn(n)}}catch(f){if(p)throw f;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw f;throw a.$track=s,c&&c.insertBefore(s,l?.parentNode===c?l:null),f}}(this,t,e)}async init(t){const e=Un(this),r=function(t){const e=t.request,r=new jn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:i}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Nt.subtitle),!t.url)return;let a;this.option=t,this.style(t.style);try{if(!r.active)return;const n=await fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const o=await n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||K(e.url)){case"srt":return{vtt:e.onVttLoad(dt(r))};case"ass":return{vtt:e.onVttLoad(pt(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const c=void 0===s?t.url:a=ut(s.vtt);if(!r.active)return;i.innerHTML="";const l=e.trackRevision+1;if(this.url!==c&&this.createTrack("metadata",c),!r.active||e.trackRevision>l)return;return a&&(e.ownedURL=a,a=void 0),c}catch(s){if(!r.active)return;throw i.innerHTML="",n.show=s,s}finally{a&&(e.scope.closed||this.url!==a?URL.revokeObjectURL(a):e.ownedURL=a)}})}}const Zn=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${i}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class Jn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=R(e.container),X(this.$container,`No container element found by ${e.container}`)),X(P(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();X("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),X(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=v.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=y(t);o.rollback=r,v.set(e,t),o.releaseContainer=()=>{v.get(e)===t&&v.delete(e)}}(t,this.$container,zn(this.$container)),function(t,e,r){const n=y(t),o=n.mountingTemplate;n.mountingTemplate=e;try{r()}finally{n.mountingTemplate=o}}(t,this,()=>{this.$container.dataset.artId=String(t.id),this.init()})}static get html(){return Zn}query(t){return R(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Jn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);if(w(this.art))return;!function(t){X(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),F(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&O(this.$player,"art-backdrop"),u&&O(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":O(this.$player,"art-destroy")}}const Qn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class to{on(t,e,r){const n=this.e||(this.e={});let o=Qn(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(Qn(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=Qn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new Jn(this),b(this).closed)return;if(this.events=new Le(this),b(this).closed)return;if(this.storage=new Bn,b(this).closed)return;if(this.icons=new _e(this),b(this).closed)return;if(this.i18n=new Ie(this),b(this).closed)return;if(this.notice=new Xe(this),b(this).closed)return;if(this.player=new Rr(this),b(this).closed)return;if(this.layers=new Be(this),b(this).closed)return;if(this.controls=new be(this),b(this).closed)return;if(this.contextmenu=new Ut(this),b(this).closed)return;if(this.subtitle=new Kn(this),b(this).closed)return;if(this.info=new Ye(this),b(this).closed)return;if(this.loading=new He(this),b(this).closed)return;if(this.hotkey=new Oe(this),b(this).closed)return;if(this.mask=new je(this),b(this).closed)return;if(this.setting=new Yn(this),b(this).closed)return;if(this.plugins=new Ur(this),b(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),no.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${no.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=y(t);return e.rollback=void 0,!e.scope.closed})(this)&&ro.push(this)}catch(r){try{x(this,ro,!0,no.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return ro}static get version(){return i}static get config(){return f}static get utils(){return ft}static get scheme(){return Nt}static get Emitter(){return to}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return Jn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:c?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:navigator?.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){x(this,ro,t,no.REMOVE_SRC_WHEN_DESTROY)}}var oo,io;return no.STYLE=Hn,no.DEBUG=!1,no.CONTEXTMENU=!0,no.NOTICE_TIME=2e3,no.SETTING_WIDTH=250,no.SETTING_ITEM_WIDTH=200,no.SETTING_ITEM_HEIGHT=35,no.RESIZE_TIME=200,no.SCROLL_TIME=200,no.SCROLL_GAP=50,no.AUTO_PLAYBACK_MAX=10,no.AUTO_PLAYBACK_MIN=5,no.AUTO_PLAYBACK_TIMEOUT=3e3,no.RECONNECT_TIME_MAX=5,no.RECONNECT_SLEEP_TIME=1e3,no.CONTROL_HIDE_TIME=3e3,no.DBCLICK_TIME=300,no.DBCLICK_FULLSCREEN=!0,no.MOBILE_DBCLICK_PLAY=!0,no.MOBILE_CLICK_PLAY=!1,no.AUTO_ORIENTATION_TIME=200,no.INFO_LOOP_TIME=1e3,no.FAST_FORWARD_VALUE=3,no.FAST_FORWARD_TIME=1e3,no.TOUCH_MOVE_RATIO=.5,no.VOLUME_STEP=.1,no.SEEK_STEP=5,no.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],no.ASPECT_RATIO=["default","4:3","16:9"],no.FLIP=["normal","horizontal","vertical"],no.FULLSCREEN_WEB_IN_BODY=!0,no.LOG_VERSION=!0,no.USE_RAF=!1,no.REMOVE_SRC_WHEN_DESTROY=!0,oo=no,io=Hn,p&&(window.Artplayer=oo,a("artplayer-style",io),setTimeout(()=>{oo.LOG_VERSION&&console.log(`%c ArtPlayer %c ${oo.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),no}); diff --git a/packages/artplayer/dist/artplayer.legacy.js b/packages/artplayer/dist/artplayer.legacy.js index 6c9ed6e2c..c243fac38 100644 --- a/packages/artplayer/dist/artplayer.legacy.js +++ b/packages/artplayer/dist/artplayer.legacy.js @@ -67,4 +67,4 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var h=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const v=globalThis.CUSTOM_USER_AGENT,y=null!=v?v:"undefined"===typeof navigator?"":navigator.userAgent,b=/^(?:(?!chrome|android).)*safari/i.test(y),w=/iPad|iPhone|iPod/i.test(y)&&("undefined"===typeof window||!window.MSStream),x=w||y.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,k=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(y)||x,$="undefined"!==typeof window&&"undefined"!==typeof document;const E={properties:["audioTracks","autoplay","buffered","controller","controls","crossOrigin","currentSrc","currentTime","defaultMuted","defaultPlaybackRate","duration","ended","error","loop","mediaGroup","muted","networkState","paused","playbackRate","played","preload","readyState","seekable","seeking","src","startDate","textTracks","videoTracks","volume"],methods:["addTextTrack","canPlayType","load","play","pause"],events:["abort","canplay","canplaythrough","durationchange","emptied","ended","error","loadeddata","loadedmetadata","loadstart","pause","play","playing","progress","ratechange","seeked","seeking","stalled","suspend","timeupdate","volumechange","waiting"],prototypes:["width","height","videoWidth","videoHeight","poster","webkitDecodedFrameCount","webkitDroppedFrameCount","playsInline","webkitSupportsFullscreen","webkitDisplayingFullscreen","onenterpictureinpicture","onleavepictureinpicture","disablePictureInPicture","cancelVideoFrameCallback","requestVideoFrameCallback","getVideoPlaybackQuality","requestPictureInPicture","webkitEnterFullScreen","webkitEnterFullscreen","webkitExitFullScreen","webkitExitFullscreen"]};class T extends Error{constructor(t){super("Failed to release ArtPlayer resources"),this.errors=t,this.name="ResourceCleanupError"}}class C{constructor(){this.cleanups=new Set,this.disposed=!1}get closed(){return this.disposed}add(t){let e=!0;const r=()=>{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new C,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof T?t.push(...e.errors):t.push(e)}if(t.length)throw new T(t)}}const L=new WeakMap,S=new WeakMap;function P(t){const e=L.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function M(t){return P(t).scope}function z(t){const e=P(t);return e.destroying||e.scope.closed}function A(t,e,r,n,o=!1){var i,a,s;const l=P(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof T?e.errors:[e])}};n&&(null==(i=t.template)?void 0:i.$video)&&d(()=>t.reset()),d(()=>l.scope.dispose()),d(()=>{var e;return null==(e=t.template||l.mountingTemplate)?void 0:e.destroy(r)});const u=e.indexOf(t);-1!==u&&e.splice(u,1),t.isDestroy=!0,o||(null==(a=l.releaseContainer)||a.call(l),l.releaseContainer=void 0),d(()=>t.emit("destroy")),d(()=>l.finalizers.dispose()),o&&l.rollback&&d(l.rollback),l.rollback=void 0,null==(s=l.releaseContainer)||s.call(l),l.releaseContainer=void 0;for(const p of c.slice(1))console.warn("Additional ArtPlayer cleanup failure:",p);if(c.length)throw c[0]}const O=new WeakMap;function R(t,e){const r=M(t).child();return O.set(e,r),r}function I(t){const e=O.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function N(t){var e;null==(e=O.get(t))||e.dispose()}function _(t,e,r,n){const o=I(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function W(t,e){return{on:(r,n)=>{_(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=I(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}function D(t){var e;if(t.composedPath)return t.composedPath();const r=[];let n=t.target;for(;n;)r.push(n),n=null!=(e=n.parentNode)?e:null;return"undefined"===typeof window||r.includes(window)||r.push(window),r}function F(t,e){return D(t).includes(e)}function V(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function Y(t){return t.getBoundingClientRect()}function B(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;";try{document.body.appendChild(t);const e=getComputedStyle(t);return{top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0}}finally{t.remove()}}function H(t,e=document){return e.querySelector(t)}function j(t,e){return t.classList.add(e)}function q(t,e){return t.classList.remove(e)}function U(t,e){return t.classList.contains(e)}function X(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function G(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function K(t,e){G(t).forEach(t=>q(t,e)),j(t,e)}function Z(t,e){return e.parentNode.replaceChild(t,e),t}function J(t){return document.createElement(t)}function Q(t,e,r="top"){k||(t.setAttribute("aria-label",e),j(t,"hint--rounded"),j(t,`hint--${r}`))}function tt(t="",e=""){const r=J("i");return j(r,"art-icon"),j(r,`art-icon-${t}`),X(r,e),r}function et(t,e,r){return t.style[e]=r,t}function rt(t,e){for(const r in e)et(t,r,e[r]);return t}function nt(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new C;let a=!1,s=()=>{};function l(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function c(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void c(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;d(l,()=>c(l)),i.closed||(l.src=e)}catch(e){l(e)}}))}),i.closed||(n.src=t)}catch(u){l(u)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){l(u)}},e.onerror=()=>l(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}class ot extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function it(t,e){if(!t)throw new ot(e);return t}function at(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function st(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function lt(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function ct(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const pt={"&":"&","<":"<",">":">","'":"'",'"':"""},ht={"&":"&","<":"<",">":">","'":"'",""":'"'},ft=/(&|<|>|'|")/g;function mt(t){return t.replace(/[&<>'"]/g,t=>pt[t]||t)}const gt=Object.defineProperty,{hasOwnProperty:vt}=Object.prototype;function yt(t,e){return vt.call(t,e)}function bt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function wt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?wt(o,i):i,gt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function xt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function kt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function $t(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const Et=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:ot,addClass:j,append:X,assToVtt:$t,capitalize:dt,clamp:ct,createElement:J,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:gt,download:lt,errorHandle:it,escape:mt,get:bt,getComposedPath:D,getExt:st,getIcon:tt,getRect:Y,getSafeAreaInsets:B,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:U,includeFromEvent:F,inverseClass:K,isBrowser:$,isIOS:w,isIOS13:x,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:k,isSafari:b,loadImg:function(t,e){return nt(t,e,void 0)},mergeDeep:wt,query:H,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:q,replaceElement:Z,secondToTime:ut,setStyle:et,setStyleText:g,setStyles:rt,siblings:G,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:V,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:Q,unescape:function(t){return t.replace(ft,t=>ht[t]||t)},userAgent:y,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function Tt(t,e){return X(t,e)}function Ct(t,e){return e.querySelector(t)}const Lt="array",St="boolean",Pt="string",Mt="number",zt="object",At="function";function Ot(t,e,r){return it(e===Pt||e===Mt||t instanceof Element,`${r.join(".")} require '${Pt}' or 'Element' type`)}const Rt={html:Ot,disable:`?${St}`,name:`?${Pt}`,index:`?${Mt}`,style:`?${zt}`,click:`?${At}`,mounted:`?${At}`,tooltip:`?${Pt}|${Mt}`,width:`?${Mt}`,selector:`?${Lt}`,onSelect:`?${At}`,switch:`?${St}`,onSwitch:`?${At}`,range:`?${Lt}`,onRange:`?${At}`,onChange:`?${At}`},It={id:Pt,container:Ot,url:Pt,poster:Pt,type:Pt,theme:Pt,lang:Pt,volume:Mt,isLive:St,muted:St,autoplay:St,autoSize:St,autoMini:St,loop:St,flip:St,playbackRate:St,aspectRatio:St,screenshot:St,setting:St,hotkey:St,pip:St,mutex:St,backdrop:St,fullscreen:St,fullscreenWeb:St,subtitleOffset:St,miniProgressBar:St,useSSR:St,playsInline:St,lock:St,gesture:St,fastForward:St,autoPlayback:St,autoOrientation:St,airplay:St,proxy:`?${At}`,plugins:[At],layers:[Rt],contextmenu:[Rt],settings:[Rt],controls:[l(s({},Rt),{position:(t,e,r)=>{const n=["top","left","right"];return it("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${St}`,html:Pt,url:Pt}],highlight:[{time:Mt,text:Pt}],thumbnails:{url:Pt,number:Mt,column:Mt,width:Mt,height:Mt,scale:Mt},subtitle:{url:Pt,name:Pt,type:Pt,style:zt,escape:St,encoding:Pt,onVttLoad:At},moreVideoAttr:zt,i18n:zt,icons:zt,cssVar:zt,customType:zt},Nt=new WeakSet;class _t{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return U(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?j(e,r):q(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(z(this.art))return;const r="function"===typeof t?t(this.art):t;if(z(this.art))return;if(r.html=r.html||"",f(r,Rt),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;it(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=R(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,n);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){j(t,`art-${r}`),j(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):X(e,t),i.html&&X(t,i.html),i.style&&rt(t,i.style),i.tooltip&&Q(t,i.tooltip)}(i,this.$parent,this.name,n,this.id,r),a.closed)return;if(r.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),r.click.call(this.art,this,t))});s.push(t)}if(r.selector&&["left","right"].includes(r.position)&&this.selector(r,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,n,i),c=!0,o.set(n,{$ref:i,events:s,option:r}),r.mounted&&r.mounted.call(this.art,i),i}catch(d){try{N(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw(null==(e=o.get(n))?void 0:e.$ref)===i&&o.delete(n),c&&this[n]===i&&(l?Object.defineProperty(this,n,l):delete this[n]),i.remove(),d}}remove(t){it(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Nt.has(e)){Nt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{N(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Nt.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Wt extends _t{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,R(t,this.$parent),k||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=W(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return l(s({},t),{html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=W(e,t),n=H('[data-value="1"]',t);n&&K(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&K(r,"art-current")})}})}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return l(s({},t),{html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=W(e,t),n=H('[data-value="default"]',t);n&&K(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&K(r,"art-current")})}})}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(dt(t))}`).join("");return l(s({},t),{html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=W(e,t),n=H('[data-value="normal"]',t);n&&K(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&K(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>l(s({},t),{html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return l(s({},t),{html:`ArtPlayer ${m}`})}({name:"version",index:50})),this.add(function(t){return e=>l(s({},t),{html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=Y(e),{height:c,width:d}=Y(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),rt(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{F(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Dt(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||(null==s?void 0:s.aborted))return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{null==s||s.removeEventListener("abort",l)}}),null==s||s.addEventListener("abort",l,{once:!0}),l}function Ft(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Vt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const Yt=new WeakMap,Bt=new WeakMap,Ht=new WeakMap;function jt(t){return Ht.get(t)||M(t)}function qt(t){const e=Yt.get(t),r=Ht.get(t);return()=>Yt.get(t)===e&&(!e||e.active())&&Ht.get(t)===r&&(!r||!r.closed)}function Ut(t){const e=Ht.get(t),r=M(t).child(),n=r.child();Ht.set(t,r),r.add(()=>{Ht.get(t)===r&&Ht.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!z(t)&&!n.closed&&Yt.get(t)===o};return Yt.set(t,o),n.add(()=>{Yt.get(t)===o&&Yt.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function Xt(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function Gt(t,e,r){Bt.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Bt.get(t)===e&&(Bt.delete(t),Xt(e))}}function Kt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Zt(t,e){const{$progress:r}=t.template,{left:n}=Y(r),o=ct((k?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:ut(i),width:o,percentage:ct(o/r.clientWidth,0,1)}}function Jt(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Zt(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Qt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=I(e),{on:a}=W(t,e);let s=()=>{};const l=Ct(".art-progress-hover",e),c=Ct(".art-progress-loaded",e),d=Ct(".art-progress-played",e),u=Ct(".art-progress-highlight",e),p=Ct(".art-progress-indicator",e),h=Ct(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Zt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?et(h,"left",0):o>e.clientWidth-a/2?et(h,"left",e.clientWidth-a+"px"):et(h,"left",o-a/2+"px")}r.indicator?X(p,r.indicator):et(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&k;if("loaded"===r&&et(c,"width",100*n+"%"),"hover"===r&&(et(l,"width",100*n+"%"),F(a,u)?function(r){const{width:n}=Zt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=null!=o?o:"";const i=h.clientWidth;n<=i/2?et(h,"left",0):n>e.clientWidth-i/2?et(h,"left",e.clientWidth-i+"px"):et(h,"left",n-i/2+"px")}(a):f(a),0===n?q(o,"art-progress-hover"):j(o,"art-progress-hover")),"played"===r&&(et(d,"width",100*n+"%"),et(p,"left",100*n+"%")),m){j(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Ft(i,()=>{q(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function te(t){return e=>l(s({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Qt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=W(t,e),a=I(e);let s=0;const l=()=>{const e=qt(t);return()=>!a.closed&&!z(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!k){let e;i(r,"click",e=>{e.target!==n&&Jt(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=Zt(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(null==n?void 0:n()){const{second:o,percentage:i}=Zt(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t)}})}function ee(t){const{option:e}=t.art;e.isLive||t.add(te({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>l(s({},t),{mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.play),s=Tt(t,o.pause);function l(){et(a,"display","flex"),et(s,"display","none")}function c(){et(a,"display","none"),et(s,"display","flex")}Q(a,i.get("Play")),Q(s,i.get("Pause")),n(a,"click",()=>{at(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>l(s({},t),{mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o}=e,i=Tt(t,o.volume),a=Tt(t,o.volumeClose),s=Tt(t,'
'),l=Tt(s,'
'),c=Tt(l,'
'),d=Tt(l,'
'),u=Tt(d,'
'),p=Tt(u,'
'),h=Tt(d,'
');function f(t){const{top:e,height:r}=Y(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)et(i,"display","none"),et(a,"display","flex"),et(h,"top","100%"),et(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;et(i,"display","flex"),et(a,"display","none"),et(h,"top",100-t+"%"),et(p,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),k)et(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>l(s({},t),{style:k?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=W(e,t);function n(){const r=`${ut(e.currentTime)} / ${ut(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!M(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!k&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=W(e,t),{icons:n}=e;Tt(t,n.screenshot),r(t,"click",()=>{at(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e;Tt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{Q(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e;Tt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{Q(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=W(e,t),{icons:n}=e;Tt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenWebOn),s=Tt(t,o.fullscreenWebOff);et(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(Q(t,i.get("Exit Web Fullscreen")),et(a,"display","none"),et(s,"display","inline-flex")):(Q(t,i.get("Web Fullscreen")),et(a,"display","inline-flex"),et(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=W(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenOn),s=Tt(t,o.fullscreenOff);et(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(Q(t,i.get("Exit Fullscreen")),et(a,"display","none"),et(s,"display","inline-flex")):(Q(t,i.get("Fullscreen")),et(a,"display","inline-flex"),et(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rne.get(t).option.selector}),gt(t,"$control_item",{get:()=>ne.get(t).item}),gt(t,"$control_value",{get:()=>ne.get(t).value})),ne.set(t,e)}function ie(t,e){t.innerHTML=e}function ae(t,e,r,n,o){const{proxy:i}=t.events,a=I(n),s=r.selector;j(n,"art-control-selector");const l=document.createElement("div");j(l,"art-selector-value"),X(l,r.html),n.textContent="",X(n,l);const d=Tt(n,'
');for(let c=0;cc(null,null,function*(){if(a.closed)return;const o=D(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++u,c=()=>!a.closed&&s===u,d=a.add(function(t,e){return re.set(t,e),()=>{re.get(t)===e&&re.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=yield r.onSelect.call(t,i,i.$control_item,n);c()&&ie(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class se extends _t{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;R(t,n);const{on:o}=W(t,n);o("mousemove",()=>{k||(this.show=!0)}),o("click",()=>{k?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=F(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(q(r,"art-hide-cursor"),j(r,"art-hover"),this.timer=Date.now()):(j(r,"art-hide-cursor"),q(r,"art-hover"))}),this.init(),M(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=I(e),{on:i}=W(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){ee(this)}add(t){if(z(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:it(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){ie(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function le(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(z(t))return;const o=F(r,e);t.isInput=o&&"INPUT"===(null==(n=r.target)?void 0:n.tagName),t.isFocus=o,t.emit(o?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),M(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(z(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),z(t))return;(!k||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),z(t))return;k?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function ce(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!z(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),M(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(z(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:qt(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Jt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=ct((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=ct(i.time+t.duration*d*l,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",ct(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${ut(u)} / ${ut(t.duration)}`))},cancel:r}}const de=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],ue=["resize","scroll","orientationchange"];const pe=new WeakMap;function he(t){const e=pe.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function fe(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=fe(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=he(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(null==o?void 0:o.capture),once:Boolean(null==o?void 0:o.once),passive:null==o?void 0:o.passive,signal:null==o?void 0:o.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||(null==c?void 0:c.aborted))return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,l),null==c||c.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):(null==c?void 0:c.aborted)?p():null==c||c.addEventListener("abort",p,{once:!0})}catch(h){try{u(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return p}function me(t){return(e,r)=>{if(z(t))return;const n=(...e)=>{if(!z(t))return r(...e)};t.on(e,n),M(t).add(()=>{t.off(e,n)})}}function ge(t){if(!t.constructor.USE_RAF)return;const e=M(t);let r=()=>{};const n=()=>{z(t)||(t.playing&&t.emit("raf"),z(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),me(t)("destroy",()=>r())}class ve{constructor(t){this.destroyEvents=new Set,function(t,e){pe.set(t,{scope:M(e),cleaning:!1})}(this,t),M(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),le(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{z(t)||(j(r,"art-hover"),t.emit("hover",!0,e))},e=>{z(t)||(q(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{z(t)||t.emit("mousemove",e)})}(t,this),function(t,e){var r,n;const{option:o,constructor:i}=t,a=me(t);a("resize",()=>{const{aspectRatio:e,notice:r}=t;"standard"===t.state&&o.autoSize&&t.autoSize(),z(t)||(t.aspectRatio=e,z(t)||(r.show=""))});const s=M(t);let l=()=>{};const c=()=>{z(t)||(l(),l=Ft(s,()=>t.emit("resize"),i.RESIZE_TIME))};a("window:orientationchange",c),a("window:resize",c);const d=null==(n=null==(r=t.template.$player.ownerDocument.defaultView)?void 0:r.screen)?void 0:n.orientation;"function"===typeof(null==d?void 0:d.addEventListener)&&e.proxy(d,"change",c)}(t,this),function(t,e){if(!k||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=ce(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=M(t),a=me(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=(null==o?void 0:o.innerHeight)||n.documentElement.clientHeight,a=(null==o?void 0:o.innerWidth)||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),z(t)||(s=!0,Ft(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;M(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){var a;if(z(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||z(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,s=i.window||(null==(a=n.ownerDocument)?void 0:a.defaultView)||window,d=(n,o,i)=>{for(const a of o){if(c())return;l.disposers.push(e.proxy(n,a,e=>{r!==l||z(t)||t.emit(`${i}:${a}`,e)}))}};d(o,de,"document"),d(s,ue,"window")}catch(u){throw o(l),u}if(c())return void o(l);const d=r;r=l,o(d)}i(),e.bindGlobalEvents=i}(t,this),ge(t)}proxy(t,e,r,n={}){return Array.isArray(e),fe(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=he(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function ye(t){if(t&&1===t.nodeType)return t}function be(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const we=new WeakMap;class xe{constructor(t){this.art=t,this.keys={},we.set(this,{subscribed:!1}),k||this.init()}init(){const t=this.art;if(z(t))return;const e=we.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{at(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!z(t)){if(t.isFocus&&function(t,e){var r,n;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const o=function(t,e){var r;const n=t.target;return 9===(null==n?void 0:n.nodeType)?n:(null==n?void 0:n.ownerDocument)||(null==(r=t.view)?void 0:r.document)||e}(t,e);let i=ye(o.activeElement);for(;null==(r=null==i?void 0:i.shadowRoot)?void 0:r.activeElement;)i=ye(i.shadowRoot.activeElement);if(i&&be(i))return!1;const a=ye(null==(n=t.composedPath)?void 0:n.call(t)[0])||ye(t.target);return!a||!be(a)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const ke={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",ke);class $e{constructor(t){this.art=t,this.languages={"zh-cn":ke},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=yt(this.languages,t)&&this.languages[t]||{}}get(t){return yt(this.language,t)&&this.language[t]||t}update(t){this.languages=wt(this.languages,t),this.init()}}const Ee={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class Te{constructor(t){const e=s(s({},Ee),t.option.icons);for(const r in e)gt(this,r,{get:()=>tt(r,e[r])})}}const Ce=new WeakMap;class Le extends _t{constructor(t){super(t),this.name="info",Ce.set(this,{revision:0}),k||this.init()}init(){var t;const e=Ce.get(this),r=++e.revision;if(null==(t=e.scope)||t.dispose(),z(this.art)||e.revision!==r)return;const n=M(this.art).child();e.scope=n,n.add(()=>{e.scope===n&&(e.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!z(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)});const h=()=>{var t;try{for(const e of u){if(!n())return;const r=Reflect.get(c,null!=(t=e.dataset.video)?t:"undefined");if(!n())return;const o="number"===typeof r?r.toFixed(2):r;if(!n())return;if(e.textContent!==o){const t=null==o?null:`${o}`;if(!n())return;e.textContent=t}}n()&&Ft(e,h,a.INFO_LOOP_TIME)}catch(r){o(r)}};n()&&h()}catch(i){o(i)}}(this.art,n,()=>{this.show=!1})}}class Se extends _t{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{et(i,"display","none"),et(s,"display",null),z(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,P(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),z(t)||n.proxy(e.$state,"click",()=>{z(t)||at(t.play())})}}const ze=new WeakMap;function Ae(t){const e=ze.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class Oe{constructor(t){this.art=t,this.timer=null,ze.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),M(t).add(()=>{t.off("destroy",e)}),M(t).add(()=>{this.destroy()})}destroy(){Ae(this)}set show(t){if(z(this.art))return;const e=ze.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){Ae(this);const i=e.revision,a=()=>!z(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(j(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(z(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",z(this.art)||e.revision!==t||q(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else q(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function Re(t,e){return function(t,e){const r=wt(e,t);return r.container=t.container,f(r,It)}(t,e)}function Ie({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ne(t,e){if(!Ie(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Ie(r)?r:void 0}const _e=new WeakMap;function We(t){return _e.get(t)||0}function De(t,e,r,n=!1){const o=e=>{z(t)||r(e)};t[n?"once":"on"](e,o),M(t).add(()=>{t.off(e,o)})}function Fe(t,e,r){for(const[n,o]of e){if(z(t)||r&&!r())return;t[n].show=o}}function Ve(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=jt(t),l=0;return{reset(){l=0,null==a||a.dispose(),q(i,"art-error")},loadStart(){q(i,"art-error")},schedule(d){(d=>c(null,null,function*(){if(z(t))return;const c=jt(t);if(c!==s&&(s=c,l=0),a&&!a.closed)return;const u=c.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!z(t)&&!u.closed&&c===jt(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}const Ye=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],Be=(()=>{if("undefined"===typeof document)return!1;const t=Ye[0],e={};for(const r of Ye){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),He={change:Be.fullscreenchange,error:Be.fullscreenerror},je={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{je.off("change",o),r()};je.on("change",o);const i=t[Be.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!je.isFullscreen)return void t();const r=()=>{je.off("change",r),t()};je.on("change",r);const n=document[Be.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>je.isFullscreen?je.exit():je.request(t,e),onchange(t){je.on("change",t)},onerror(t){je.on("error",t)},on(t,e){const r=He[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=He[t];r&&document.removeEventListener(r,e,!1)},raw:Be};function qe(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(je,{isFullscreen:{get:()=>Boolean(document[Be.fullscreenElement])},element:{enumerable:!0,get:()=>document[Be.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Be.fullscreenEnabled])}});const Ue=new WeakMap;function Xe(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function Ge(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ue.get(t);if(!n){n=new WeakMap,Ue.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Xe(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Xe(i))}function Ke(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,u=!1,p=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!u&&r&&Ge(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Dt(i,t.document,t.changeEvent,m),Dt(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){var e;null==(e=Ue.get(t.document))||e.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,c&&!u&&r&&Ge(t),u?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):p?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Ze(t,e){const r=M(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,u=!1,p=!1;function h(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch(t){}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),h()}),Dt(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=Ue.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||z(t))return;s=r;const o=l,a=()=>z(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),Dt(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!z(t)&&t.emit("fullscreenError",r)}),{get:()=>!z(t)&&i(),set(n){if(z(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?u=!1:d&&(u=!0),null==a||a.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();p=!0,d=c;const s=Ke(e,r,c,()=>{!z(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw z(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const Je=new WeakSet;function Qe(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function tr(t){Je.delete(t),t.removeEventListener("webkitbeginfullscreen",er),t.removeEventListener("webkitpresentationmodechanged",er)}function er(t){var e;if(Je.has(this)&&Qe(this,"webkitbeginfullscreen"===t.type)){tr(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function rr(t){Je.add(t),t.addEventListener("webkitbeginfullscreen",er),t.addEventListener("webkitpresentationmodechanged",er)}function nr(t){const{$video:e}=t.template,r=M(t).child();let n=!1,o=Qe(e),i=o,a=!1,s=0;const l=()=>Qe(e,n);function c(r){if(z(t)||(c=e,Je.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>z(t)||l()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{var t;s++,i=!1,a&&rr(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Dt(r,e,"webkitbeginfullscreen",()=>c(!0)),Dt(r,e,"webkitendfullscreen",()=>c(!1)),Dt(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!z(t)&&l(),set(r){if(z(t))return;const n=++s;if(i=Boolean(r),r){if(tr(e),t.state="fullscreen",z(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,rr(e)),l()&&e.webkitExitFullscreen()}}}function or(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function ir({node:t,parent:e,next:r}){var n;if(!e)return void(null==(n=t.parentNode)||n.removeChild(t));const o=(null==r?void 0:r.parentNode)===e?r:null;t.parentNode===e&&t.nextSibling===o||e.insertBefore(t,o)}function ar(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function sr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function lr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),Dt(o,e,"click",n),Dt(o,l,"click",()=>{at(t.play())}),Dt(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const u=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};Dt(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=ar(i.left,i.top,sr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:u,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function cr(t){const{$player:e,$video:r}=t.template,n=M(t).child();let o,i,a=0,c=!1,d=!1;const u=()=>!z(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{ir(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(z(t))return;const r=++a;d=!1,p(),z(t)||r!==a||(null==o||o.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(z(t))return;const m=++a;if(c)d=!0;else if(t.state="mini",!z(t)&&m===a){null!=i||(i=or(r)),e.classList.add("art-mini");try{if(!o){c=!0;try{o=lr(t,n,u,h)}finally{c=!1}}if(d)return d=!1,void f();if(!o||z(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),z(t)||m!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:l(s({},ar(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,sr(o.element));if(z(t)||m!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),z(t)||m!==a)return;t.storage.set("left",i.left)}z(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,z(t)||m!==a&&!r||(p(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),g}}}return n.add(()=>{a++;try{p()}finally{null==o||o.cancelDrag(),e.classList.remove("art-mini")}}),{get:u,set(t){t?f():h()}}}const dr=new WeakSet,ur=t=>"picture-in-picture"===t.webkitPresentationMode;function pr(t){dr.delete(t),t.removeEventListener("webkitpresentationmodechanged",hr),t.removeEventListener("enterpictureinpicture",hr)}function hr(){var t;if(dr.has(this)&&ur(this)){pr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function fr(t){dr.add(t),t.addEventListener("webkitpresentationmodechanged",hr),t.addEventListener("enterpictureinpicture",hr)}function mr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function gr(t,e,r){return new Promise((n,o)=>{if(z(t)||e===t.url)return void n();const i=Ut(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const d=()=>!s&&i.active(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!d())return;const p=a.child();let h=!1,f=!1,m=!1;const g=function(t,e,r){let n,o=!1,i=!1,a=!1,s=We(t);const l=()=>a||We(t)!==s,c=()=>{var e,r;return!!(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)};return{restore(){if(!r()||l())return;const i=We(t);t.currentTime=e,s=We(t),s>i+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}(t,r,d),v=()=>c(null,null,function*(){if(t.aspectRatio=o,d()){if(n)try{yield t.play()}catch(e){}d()&&(t.notice.show="",l())}}),y=()=>{var e,r;if(d()&&!f&&h)try{if(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)return;if(!d())return;if(m||(m=!0,t.playbackRate=s),!g.ready()||!d()||f)return;f=!0,p.dispose(),v().catch(u)}catch(n){u(n)}},b={"video:error":u,"video:loadedmetadata":()=>{if(d())try{g.restore()}catch(t){u(t)}},"video:canplay":()=>{h=!0,y()},"video:seeked":y,seek:g.manual},w=a.child(),x=[],k=Object.keys(b);for(const e of k)mr(w,t,e,t=>{i.acceptingEvents&&x.push([e,t])},!1);if(Gt(t,i,e),!d())return;if(t.notice.show="",!d())return;const $=()=>{if(w.dispose(),!e)return void l();const r={};for(const e of k)r[e]=mr(p,t,e,b[e],"video:seeked"!==e);for(const[t,e]of x){if(!d()||p.closed)break;r[t](e)}x.length=0};i.assigned?$():i.onAssigned=$}catch(p){u(p)}})}function vr(t){const{option:e,template:{$video:r}}=t;gt(t,"url",{get:()=>r.src,set(n){return c(this,null,function*(){if(z(t))return;const o=function(t){const e=Bt.get(t);return Bt.delete(t),e||Ut(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield Vt(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||st(n),s=e.customType[a];if(a&&s){if(!(yield Vt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;mr(l,t,"video:canplay",()=>{c=!d}),mr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Kt(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||mr(o.scope,t,"video:canplay",e)}}catch(i){Kt(o,i)}finally{Xt(o)}})}})}const yr=[function(t){const{template:{$video:e}}=t;gt(t,"attr",{value(t,r){const n=e;if(void 0===r)return n[t];n[t]=r}})},function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;gt(t,"play",{value(){return c(this,null,function*(){const a=qt(t),s=yield i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})},function(t){const{notice:e}=t;gt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${ut(t.currentTime)} / ${ut(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;gt(t,"forward",{set(e){r.seek=t.currentTime+e}}),gt(t,"backward",{set(e){r.seek=t.currentTime-e}})},function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;gt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=ct(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),gt(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})},function(t){const{$video:e}=t.template;gt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){_e.set(t,We(t)+1)}(t),e.currentTime=ct(n,0,t.duration))}})},function(t){gt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})},function(t){const e=e=>gr(t,e,0);gt(t,"switchQuality",{value:e=>gr(t,e,t.currentTime)}),gt(t,"switchUrl",{value:e}),gt(t,"switch",{set:e})},function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;gt(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;gt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!z(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ne({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(z(t))return;"width"===(null==r?void 0:r.axis)?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,z(t)||t.emit("aspectRatio",i)}}})},function(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=qt(t);return new Promise((a,s)=>{const l=r=>{try{!z(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}gt(t,"getDataURL",{value:()=>o(!1)}),gt(t,"getBlobUrl",{value:()=>o(!0)}),gt(t,"screenshot",{value:e=>c(null,null,function*(){const n=qt(t),o=yield t.getDataURL();if(!z(t)&&n()){const i=e||`artplayer_${ut(r.currentTime)}`;!z(t)&&n()&<(o,`${i}.png`),!z(t)&&n()&&t.emit("screenshot",o)}return o})})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(z(t))return;const i=function(t){const e=je.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>qe(t,e.requestFullscreen,void 0),exit:()=>qe(r,e.exitFullscreen)}}(o);i?gt(t,"fullscreen",Ze(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?gt(t,"fullscreen",nr(t)):gt(t,"fullscreen",{get:()=>!1,set(){z(t)||(r.show=e.get("Fullscreen Not Supported"))}}),gt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),M(t).add(()=>{t.off("video:loadedmetadata",i)})},function(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(ir(t.placement),r()))}return M(t).add(()=>{var t;n+=1;const i=r;if(r=void 0,i)try{o(i,()=>!0)}catch(a){try{e.parentNode!==i.placement.parent&&(null==(t=e.parentNode)||t.removeChild(e))}catch(s){throw new T([a,s])}throw a}}),i=>{if(z(t))return;const a=++n,s=()=>a===n&&!z(t);if(i){r||(r={placement:or(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);gt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})},function(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?gt(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=M(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch(t){}}function u(e,r,n){e.then(()=>{!r||!z(t)&&a||d()},e=>{z(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Dt(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!z(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Dt(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!z(t)&&o()?e:null,set(n){if(z(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",z(t)||c!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?gt(t,"pip",function(t){const{$video:e}=t.template,r=M(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(z(t)||dr.has(e))return;const s=ur(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),z(t)||i!==l||ur(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&fr(e),ur(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Dt(r,e,l,()=>s());return{get:()=>!z(t)&&ur(e),set(r){var n;if(z(t))return;const l=++i,c=a;if(r){if(!1===(null==(n=e.webkitSupportsPresentationMode)?void 0:n.call(e,"picture-in-picture")))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(pr(e),t.state="pip",z(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,fr(e)),ur(e)&&e.webkitSetPresentationMode("inline");z(t)||l!==i||c!==a||ur(e)!==Boolean(r)||s(!0)}}}(t)):gt(t,"pip",{get:()=>!1,set(){z(t)||(r.show=e.get("PIP Not Supported"))}})},function(t){const{$video:e}=t.template,r=t;gt(t,"loaded",{get:()=>r.loadedTime/e.duration}),gt(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})},function(t){gt(t,"played",{get:()=>t.currentTime/t.duration})},function(t){const{$video:e}=t.template;gt(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})},function(t){const{$container:e,$player:r,$video:n}=t.template;gt(t,"autoSize",{value(){if(z(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Ie(o))return;const i=Y(e),a=Ne(i,o.width/o.height);a&&!z(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})},function(t){const e=t;gt(t,"rect",{get:()=>Y(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}gt(t,"x",{get:()=>e.left+window.pageXOffset}),gt(t,"y",{get:()=>e.top+window.pageYOffset})},function(t){const{template:{$player:e},i18n:r,notice:n}=t;gt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){z(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,z(t)||t.emit("flip",o))}})},function(t){gt(t,"mini",cr(t))},function(t){const{template:{$poster:e}}=t;gt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){et(e,"backgroundImage",`url(${t})`)}})},function(t){const{$container:e,$video:r}=t.template;gt(t,"autoHeight",{value(){if(z(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Ie(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||z(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})},function(t){const{$player:e}=t.template;gt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})},function(t){gt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})},function(t){gt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})},function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];gt(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;n{if(!z(t))switch(e.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,z(t)||gt(t,"airplay",{value(){if(!z(t))if(i){const e=o.webkitShowPlaybackTargetPicker;if(z(t))return;Reflect.apply(e,o,[]),z(t)||t.emit("airplay")}else{const n=e.get("AirPlay Not Available");z(t)||(r.show=n)}}}))},function(t){gt(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:(null==i?void 0:i.html)||"",selector:e,onSelect(e,r,i){return c(this,null,function*(){const r=function(t){return t&&re.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!z(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!z(t)&&r()&&(n.show=i)}return e.html})}})}})},function(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,l=M(t).child(),c=!1;function d(){const e=l;l=M(t).child(),o=void 0,c=!1,a=void 0,e.dispose()}function u(){const i=a,c=l;if(!i||!o)return;const d=()=>{var e;return!z(t)&&!c.closed&&l===c&&a===i&&i.sourceActive()&&(null==(e=t.controls)?void 0:e.thumbnails)===i.element};if(!d())return;const u=r.clientWidth*i.percentage;if(!(u>0&&ud-h/2?d-h+"px":u-h/2+"px"}}(e.thumbnails,{imageWidth:o.naturalWidth,videoWidth:n.videoWidth,videoHeight:n.videoHeight,progressWidth:r.clientWidth,position:u}));for(const[t,e]of Object.entries(p)){if(!d())return;et(i.element,t,e)}}me(t)("setBar",(r,n,s)=>{var p;const h=null==(p=t.controls)?void 0:p.thumbnails,{url:f,scale:m}=e.thumbnails;if(!z(t)&&h&&f&&("hover"===r||"played"===r&&s&&k)){if(i!==h){const t=I(h);if(t.closed)return;i=h,t.add(()=>{i===h&&(i=void 0,d())})}if(a={percentage:n,element:h,sourceActive:qt(t)},o)u();else if(!c){const t=l;c=!0,function(t,e,r){return nt(t,e,r)}(f,m,t).then(e=>{l!==t||t.closed||(c=!1,o=e,u())}).catch(e=>{l!==t||t.closed||(c=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),gt(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{z(t)||!e.url||t.option.isLive||z(t)||(t.option.thumbnails=e,d())}})},function(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{z(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Ve(t);!function(t,e){De(t,"video:canplay",()=>{e.reset(),Fe(t,[["loading",!1]])}),De(t,"video:canplay",()=>{Fe(t,[["loading",!1],["controls",!0],["mask",!0]]),z(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;De(t,"video:ended",()=>{if(e.loop){const e=qt(t);if(t.seek=0,z(t)||!e())return;at(t.play()),e()&&Fe(t,[["controls",!1],["mask",!1]],e)}else Fe(t,[["controls",!0],["mask",!0]])})}(t),De(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;De(t,"video:loadedmetadata",()=>{t.emit("resize"),k&&Fe(t,[["loading",!1],["controls",!0],["mask",!0]])}),De(t,"video:loadstart",()=>{e.loadStart(),Fe(t,[["loading",!0],["mask",!1],["controls",!0]])}),De(t,"video:pause",()=>{Fe(t,[["controls",!0],["mask",!0]])}),De(t,"video:play",()=>{Fe(t,[["mask",!1]]),z(t)||et(r,"display","none")}),De(t,"video:playing",()=>Fe(t,[["mask",!1]])),De(t,"video:progress",()=>{t.playing&&Fe(t,[["loading",!1]])}),De(t,"video:seeked",()=>Fe(t,[["loading",!1],["mask",!0]])),De(t,"video:seeking",()=>Fe(t,[["loading",!0],["mask",!1]])),De(t,"video:timeupdate",()=>Fe(t,[["mask",!1]])),De(t,"video:waiting",()=>Fe(t,[["loading",!0],["mask",!1]]))}(t,e)},function(t){if(z(t))return;const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const s in e.moreVideoAttr){if(z(t))return;const r=e.moreVideoAttr[s];if(z(t))return;t.attr(s,r)}if(z(t))return;if(e.muted){const r=e.muted;if(z(t))return;t.muted=r}if(z(t))return;if(e.volume){const r=ct(e.volume,0,1);if(z(t))return;n.volume=r}if(z(t))return;const i=r.get("volume");if(z(t))return;if("number"===typeof i&&(n.volume=ct(i,0,1)),z(t))return;if(e.poster){const r=`url(${e.poster})`;if(z(t))return;et(o,"backgroundImage",r)}if(z(t))return;if(e.autoplay){const r=e.autoplay;if(z(t))return;n.autoplay=r}if(z(t))return;if(e.playsInline){if(z(t))return;if(n.playsInline=!0,z(t))return;n["webkit-playsinline"]=!0}if(z(t))return;if(e.theme){const r=e.cssVar,n=e.theme;if(z(t))return;r["--art-theme"]=n}for(const s in e.cssVar){if(z(t))return;const r=e.cssVar[s];if(z(t))return;t.cssVar(s,r)}if(z(t))return;const a=e.url;z(t)||(t.url=a)}];class br{constructor(t){if(!z(t)){vr(t);for(const e of yr){if(z(t))return;e(t)}}}}const wr=new WeakMap,xr="art-auto-orientation-fullscreen";function kr(t){if(wr.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const $r="art-auto-orientation",Er=["width","height","transform-origin","transform"];function Tr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Ie(t)&&Ie(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=M(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains($r);r.classList.remove($r),n&&(t.isRotate=!1,z(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=B();if(z(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=Er.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add($r),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;z(t)||(r?o?s(!1):e()&&(i(),i=Ft(n,()=>{o||s(!0)},Number(null!=(l=t.constructor.AUTO_ORIENTATION_TIME)?l:0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(xr),t&&(t.cancelled=!0,kr(t),t.settled&&wr.get(t.orientation)===t&&wr.delete(t.orientation))}return M(t).add(o),i=>{var a,s;if(z(t))return;if(!i)return void o();if(n&&!n.cancelled&&wr.get(n.orientation)===n)return;const l=null==(s=null==(a=r.ownerDocument.defaultView)?void 0:a.screen)?void 0:s.orientation;if("function"!==typeof(null==l?void 0:l.lock)||"function"!==typeof l.unlock||!e())return;const c={orientation:l,cancelled:!1,settled:!1};n=c,wr.set(l,c);const d=()=>!z(t)&&!c.cancelled&&n===c&&wr.get(l)===c,u=e=>{c.settled=!0;const o=d();wr.get(l)===c&&wr.delete(l),n===c&&(n=void 0),o&&(r.classList.remove(xr),t.notice.show=e)};try{const t=l.lock(l.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{c.settled=!0,d()?r.classList.add(xr):(kr(c),wr.get(l)===c&&wr.delete(l))}).catch(u)}catch(p){u(p)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),M(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Cr(t){return t.get("times")||{}}function Lr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||z(t))return()=>{};const s=Ct(".art-auto-playback-last",a),l=Ct(".art-auto-playback-jump",a),c=Ct(".art-auto-playback-close",a);Tt(c,r.close);const d=I(a);let u,p=0;const h=()=>{const r=++p;if(null==u||u.dispose(),d.closed||z(t)||p!==r)return;const h=d.child();u=h;const f=()=>u===h&&!h.closed&&!z(t);h.add(()=>{u===h&&(u=void 0,et(a,"display","none"))});const m=jt(t).add(()=>{h.dispose()});h.add(()=>{m()});const g=Cr(n)[t.option.id||t.option.url];if(!f())return;if(et(a,"display","none"),!f()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!f())return;if(et(a,"display","flex"),!f())return;const v=`${e.get("Last Seen")} ${ut(g)}`;if(!f())return;if(s.textContent=v,!f())return;const y=e.get("Jump Play");if(!f())return;if(l.textContent=y,!f())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{f()&&r()});h.add(()=>{t.events.remove(n)})};if(b(c,()=>{et(a,"display","none")}),!f())return;if(b(l,()=>{t.seek=g,f()&&(at(t.play()),f()&&(et(i,"display","none"),f()&&et(a,"display","none")))}),!f())return;let w=()=>{},x=!1;const k=()=>{!x&&f()&&(x=!0,w(),Ft(h,()=>{f()&&et(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",k),w=h.add(()=>{t.off("video:timeupdate",k)}),x&&w()};return()=>{_(t,a,"ready",h),_(t,a,"restart",h)}}(t);return function(t){const{storage:e,constructor:r}=t;me(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Cr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;z(t)||(o.length>i&&delete n[o[0]],n[a]=s,z(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Cr(e)},clear:()=>e.del("times"),delete(t){const r=Cr(e);return delete r[t],e.set("times",r),r}}}function Sr(t){let e,r=0;return{start:n=>{const o=++r;if(null==e||e.scope.dispose(),o!==r||z(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:jt(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{(null==e?void 0:e.active)||q(t.template.$player,"art-fast-forward")}}),Ft(i.scope,()=>{if(e!==i||z(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||z(t))return;t.playbackRate=r,e!==i||i.scope.closed||z(t)||j(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,null==e||e.scope.dispose()}}}function Pr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Sr(t),i=me(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return U(r,"art-fast-forward")}}}function Mr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return U(n,"art-lock")}function i(){z(t)||(j(n,"art-lock"),z(t)||(t.isLock=!0,z(t)||t.emit("lock",!0)))}function a(){z(t)||(q(n,"art-lock"),z(t)||(t.isLock=!1,z(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=I(e);if(n.closed||z(t))return;const o=Tt(e,r.lock);if(n.closed||z(t))return;const i=Tt(e,r.unlock);n.closed||z(t)||(et(o,"display","none"),_(t,e,"lock",e=>{z(t)||(et(o,"display",e?"inline-flex":"none"),n.closed||z(t)||et(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function zr(t){return me(t)("control",e=>{e?q(t.template.$player,"art-mini-progress-bar"):j(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Ar{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){z(t.art)||!e.miniProgressBar||e.isLive||t.add(zr),!z(t.art)&&e.lock&&k&&t.add(Mr),z(t.art)||!e.autoPlayback||e.isLive||t.add(Lr),!z(t.art)&&e.autoOrientation&&k&&t.add(Tr),!z(t.art)&&e.fastForward&&k&&!e.isLive&&t.add(Pr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!z(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(z(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(z(t.art))return t;let o=n;const i=yt(t,o);if(z(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return z(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),z(t.art)||gt(t,o,{value:r})),t}(this,t,e)}}const Or=new WeakMap;function Rr(t){return!t.closed&&!Or.get(t)}function Ir(t){Or.set(t,(Or.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Or.get(t)||1)-1;r?Or.set(t,r):Or.delete(t)}}const Nr=new WeakMap,_r=new WeakMap,Wr=["$parent","$parents","$option","$events","$formatted"];function Dr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Nr.get(o);if(!t||!t.owner.active||(null==(e=t.owner.scope)?void 0:e.closed)||!t.option.includes(o))return!1;if(!t.parent)return t.owner.root===t.option;if((null==(r=Nr.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function Fr(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function Vr(t){const e=Nr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Yr(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>Gr(t,o)])try{e()}catch(d){d instanceof T?l.push(...d.errors):l.push(d)}if(r.closed||z(t)||(o.push(...i.splice(0)),Xr.set(r,o),qr.set(e,r),Ur.set(e,n)),a(),l.length)throw new T(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function tn(t,e,r,n,o,i){const a=i||Zr(e);if(!Rr(a)||z(t))return;const s=t.proxy(r,n,e=>{if(Rr(a)&&!z(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Rr(a)||z(t)?t.events.remove(s):(Vr(e).events.push(s),i&&i!==qr.get(e)&&i.add(()=>{const r=Vr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function en(t,e,r,n){const o=Zr(e);if(!Rr(o)||z(t))return;const i=(...e)=>{if(Rr(o)&&!z(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function rn(t){var e,r;const{art:n,active:o}=t,{controls:i,constructor:{SETTING_WIDTH:a,SETTING_ITEM_HEIGHT:s},template:{$player:l,$setting:c,$bottom:d}}=n;if(!i.setting||!t.show||!o)return;const u=l.getBoundingClientRect(),p=i.setting.getBoundingClientRect(),h=u.width/l.offsetWidth||1,f=(p.left-u.left+p.width/2)/h-l.clientLeft,m=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:l.clientWidth,containerHeight:l.clientHeight,requestedWidth:(null==(r=null==(e=o[0])?void 0:e.$parent)?void 0:r.width)||a,rows:o.length+(o===t.option?0:1),rowHeight:s,controlCenter:f,bottom:Number.parseFloat(getComputedStyle(c).bottom)||0,padding:Number.parseFloat(getComputedStyle(d).paddingLeft)||0});c.style.height=`${m.height}px`,c.style.width=`${m.width}px`,n.isRotate||k||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const nn=new WeakMap;function on(t){nn.delete(t)}const an=new WeakMap;function sn(t,e){e?an.set(t,e):an.delete(t)}function ln(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=an.get(t),i=null==o?void 0:o();for(const a of["html","icon","tooltip"]){const t=null==(e=r.get(a))?void 0:e.value;t instanceof Node&&n.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{var e,a;for(const n of Reflect.ownKeys(t))!r.has(n)&&(null==(e=Object.getOwnPropertyDescriptor(t,n))?void 0:e.configurable)&&Reflect.deleteProperty(t,n);for(const[n,o]of r)Object.defineProperty(t,n,o);null==i||i(),sn(t,o);for(const{node:t,parent:r,next:o}of n)r?r.insertBefore(t,(null==o?void 0:o.parentNode)===r?o:null):null==(a=t.parentNode)||a.removeChild(t)}}const cn=new WeakMap;function dn(t,e,r,n,o,i,a,s){return c(this,null,function*(){try{const l=Zr(e),c=Zr(i),d=(cn.get(i)||0)+1;cn.set(i,d);const u=()=>Rr(l)&&Rr(c)&&!z(t.art)&&cn.get(i)===d;if(null==s||s(),!u())return;const p=yield o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}})}function un(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const pn=new WeakMap;function hn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof T?e.push(...r.errors):e.push(r)}if(e.length)throw new T(e)}function fn(t){var e;null==(e=pn.get(t))||e()}function mn(t,e){const r=t.find(e.name);if(z(t.art))return r||e;if(!r)return t.add(e);on(r),fn(r);const n=ln(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?un(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=Qr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Ir(Hr(t)))}catch(l){try{hn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,hn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,hn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>jr(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)pn.get(t)===h&&pn.delete(t);if(z(t.art))return void d.dispose();const e=r.$item;try{hn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>null==s?void 0:s(),()=>{i&&o&&i.insertBefore(o,(null==a?void 0:a.parentNode)===i?a:null)},()=>t.format(),()=>{if(p){t.active=l,l&&t.cache.has(l)&&K(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(f){console.warn("ArtPlayer setting restore failed:",f)}},f=()=>u&&!z(t.art)&&pn.get(r)===h;for(const v of d.items)pn.set(v,h);const m=M(t.art).add(()=>{u=!1;for(const t of d.items)pn.get(t)===h&&pn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!(null==o?void 0:o.enumerable)||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,f),!f())return r;if(t.format(),!f())return r;if(t.createItem(r,!0),!f())return r;if(p=!0,t.render(),!f())return r;u=!1;for(const t of d.items)pn.get(t)===h&&pn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const gn=new WeakMap;function vn(t,e,r){gt(t,`$${e}`,{configurable:!0,get:()=>r}),gt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",X(r,t)}})}function yn(t,e,r=!1){var n,o;const i=function(t){const e=pn.get(t);return()=>!e||pn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";yt(e,"switch")&&(l="switch"),yt(e,"range")&&(l="range"),yt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=M(t)){const n=qr.get(e);(!n||Rr(n)||n.closed)&&Jr(t,e);const o=r.child();return qr.set(e,o),Ur.set(e,r),Xr.set(o,Vr(e).events),o.add(()=>{Gr(t,Xr.get(o))}),o}(t.art,e,Hr(a)),p=()=>Rr(u)&&!z(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(sn(e),j(h,"art-setting-item"),et(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=Tt(h,'
'),f=Tt(h,'
'),m=document.createElement("div");switch(j(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;X(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;X(m,t)}else X(m,c.check)}if(X(i,m),!p())return;vn(e,"icon",m);const g=document.createElement("div");j(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;X(g,v),X(i,g),vn(e,"html",g);const y=document.createElement("div");j(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(X(y,b),X(f,y),vn(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");j(t,"art-setting-item-right-icon");const r=Tt(t,c.switchOn),n=Tt(t,c.switchOff),o=e.switch;if(!p())return;et(o?n:r,"display","none"),X(f,t),gt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;sn(e,()=>{const t=i;return()=>{i=t}}),gt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(et(n,"display","none"),et(r,"display",null)):(et(n,"display",null),et(r,"display","none"))}});break}case"range":{const t=document.createElement("div");j(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",X(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!p())return;Reflect.set(r,i,String(t))}j(r,"art-setting-range"),X(f,t),gt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;sn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),gt(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(null==(o=e.selector)?void 0:o.length){const t=document.createElement("div");j(t,"art-setting-item-right-icon"),X(t,c.arrowRight),X(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=Zr(e),a=(t,r,n)=>tn(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>dn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>dn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{var o,i;if(null==(o=e.selector)?void 0:o.length)t.render(e.selector);else{if(null==(i=e.$parent)?void 0:i.onSelect)return dn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&j(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>dn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,h,l),!p())return;gt(e,"$item",{configurable:!0,get:()=>h}),r&&(null==s?void 0:s.parentNode)?s.replaceWith(h):X(a,h),e.mounted&&p()&&Ft(u,()=>{var r;if(!z(t.art))try{const n=null==(r=e.mounted)?void 0:r.call(t.art,h,e);Promise.resolve(n).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(n){console.warn("ArtPlayer setting mounted failed:",n)}},0)}catch(f){try{u.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw h.remove(),f}}function bn(t,e=t.option){var r;if(z(t.art))return;const n=t.cache.get(e);if(n&&!Rr(Hr(n)))return;const o=(gn.get(t)||0)+1;gn.set(t,o);const i=()=>gn.get(t)===o&&!z(t.art),a=t.active,s=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),l=()=>{t.active=a,a&&t.cache.has(a)&&K(t.cache.get(a),"art-current");for(const[e,r,n]of s)t.$parent.style.setProperty(e,r,n)};if(t.active=e,n)try{K(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Hr(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=M(t.art).child();return Br.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!z(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;j(n,"art-setting-panel"),X(t.$parent,n),K(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=_r.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=M(e).child(),n=(t,n)=>{if(r.closed||z(e))return;const o=(...t)=>{if(!r.closed&&!z(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=F(r,e.controls.setting),o=F(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||z(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),en(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),en(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(dt(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),en(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{en(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Yr(e,t)}check(t){!function(t,e){(null==e?void 0:e.$parent)&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&K(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=_r.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;oVr(t).parent},$parents:{get:()=>Vr(t).parents},$option:{get:()=>Vr(t).option},$events:{get:()=>Vr(t).events},$formatted:{get:()=>!0}}),Nr.set(t,{parent:r,parents:n,option:o,events:(null==a?void 0:a.events)||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Yr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){rn(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&jr(n)}catch(i){r.push(i)}}try{Jr(t.art,e)}catch(i){i instanceof T?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new T(r)}(this,t)}remove(t){const e=this.find(t);it(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{on(t),fn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>null==n?void 0:n.remove(),()=>this.render()])try{a()}catch(i){i instanceof T?o.push(...i.errors):o.push(i)}if(o.length)throw new T(o)}update(t){return mn(this,t)}add(t,e=this.option){var r;if(z(this.art))return t;let n=!1;this.traverse(e=>{n||(n=e===t)});const o=e.length,i=n?void 0:function(t){const e={};nn.set(t,e);const r=()=>nn.get(t)===e;return{current:r,finish(){r()&&nn.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(z(this.art)||i&&!i.current())throw s;if(e[o]===t&&e.splice(o,1),!n&&a){try{this.inactivate(t)}catch(l){console.warn("ArtPlayer setting cleanup failed:",l)}null==(r=t.$item)||r.remove()}throw s}finally{null==i||i.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");et(i,"height",`${o}px`),j(i,"art-setting-item"),j(i,"art-setting-item-back");const a=Tt(i,'
'),s=document.createElement("div");j(s,"art-setting-item-left-icon"),X(s,n),X(a,s),X(a,e.$parent.html),tn(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Hr(r)),X(r,i)}(this,t)}createItem(t,e=!1){yn(this,t,e)}render(t=this.option){bn(this,t)}}class kn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch(e){return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch(r){this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch(e){delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch(t){this.settings={}}}}const $n='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class En{constructor(t){var e;this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=null==(e=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope))?void 0:e.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}run(t){return c(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const Tn=new WeakMap;function Cn(t){return Tn.get(t)}function Ln(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const Sn=_t;class Pn extends Sn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=M(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return Tn.set(t,n),r.add(()=>{Ln(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){var t,e;return null==(e=null==(t=this.art.template.$video)?void 0:t.textTracks)?void 0:e[0]}get activeCues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.activeCues)||[])}get cues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.cues)||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?rt(r,t):et(r,t,e)}update(){!function(t){const e=Cn(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?mt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return c(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=l(s(s({},o.subtitle),e),{url:t}),a=Cn(this),c=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===c&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=Cn(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(c)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const h=n.track;n.track=u,t.destroyEvent=c,s.onload=null,s.onerror=null,p=!0;try{null==h||h.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&Ln(n)}}catch(h){if(p)throw h;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,(null==c?void 0:c.parentNode)===l?c:null),h}}(this,t,e)}init(t){return c(this,null,function*(){const e=Cn(this),r=function(t){const e=t.request,r=new En(t.scope);return t.request=r,t.revision+=1,null==e||e.cancel(),r}(e),{notice:n,template:{$subtitle:o}}=this.art;return r.run(()=>c(this,null,function*(){if(!this.textTrack)return null;if(f(t,It.subtitle),!t.url)return;let i;this.option=t,this.style(t.style);try{if(!r.active)return;const n=yield fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const a=yield n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||st(e.url)){case"srt":return{vtt:e.onVttLoad(xt(r))};case"ass":return{vtt:e.onVttLoad($t(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=kt(s.vtt);if(!r.active)return;o.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return i&&(e.ownedURL=i,i=void 0),l}catch(a){if(!r.active)return;throw o.innerHTML="",n.show=a,a}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}}))})}}const Mn=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${m}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class zn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=H(e.container),it(this.$container,`No container element found by ${e.container}`)),it(V(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();it("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),it(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=S.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=P(t);o.rollback=r,S.set(e,t),o.releaseContainer=()=>{S.get(e)===t&&S.delete(e)}}(t,this.$container,un(this.$container)),function(t,e,r){const n=P(t),o=n.mountingTemplate;n.mountingTemplate=e;try{r()}finally{n.mountingTemplate=o}}(t,this,()=>{this.$container.dataset.artId=String(t.id),this.init()})}static get html(){return Mn}query(t){return H(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=zn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);if(z(this.art))return;!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),Z(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&j(this.$player,"art-backdrop"),k&&j(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":j(this.$player,"art-destroy")}}const An=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class On{on(t,e,r){const n=this.e||(this.e={});let o=An(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(An(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=An(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new zn(this),M(this).closed)return;if(this.events=new ve(this),M(this).closed)return;if(this.storage=new kn,M(this).closed)return;if(this.icons=new Te(this),M(this).closed)return;if(this.i18n=new $e(this),M(this).closed)return;if(this.notice=new Oe(this),M(this).closed)return;if(this.player=new br(this),M(this).closed)return;if(this.layers=new Se(this),M(this).closed)return;if(this.controls=new se(this),M(this).closed)return;if(this.contextmenu=new Wt(this),M(this).closed)return;if(this.subtitle=new Pn(this),M(this).closed)return;if(this.info=new Le(this),M(this).closed)return;if(this.loading=new Pe(this),M(this).closed)return;if(this.hotkey=new xe(this),M(this).closed)return;if(this.mask=new Me(this),M(this).closed)return;if(this.setting=new xn(this),M(this).closed)return;if(this.plugins=new Ar(this),M(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Nn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Nn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=P(t);return e.rollback=void 0,!e.scope.closed})(this)&&In.push(this)}catch(r){try{A(this,In,!0,Nn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return In}static get version(){return m}static get config(){return E}static get utils(){return Et}static get scheme(){return It}static get Emitter(){return On}static get validator(){return f}static get kindOf(){return f.kindOf}static get html(){return zn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:b?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:null==navigator?void 0:navigator.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){A(this,In,t,Nn.REMOVE_SRC_WHEN_DESTROY)}}var _n,Wn;return Nn.STYLE=$n,Nn.DEBUG=!1,Nn.CONTEXTMENU=!0,Nn.NOTICE_TIME=2e3,Nn.SETTING_WIDTH=250,Nn.SETTING_ITEM_WIDTH=200,Nn.SETTING_ITEM_HEIGHT=35,Nn.RESIZE_TIME=200,Nn.SCROLL_TIME=200,Nn.SCROLL_GAP=50,Nn.AUTO_PLAYBACK_MAX=10,Nn.AUTO_PLAYBACK_MIN=5,Nn.AUTO_PLAYBACK_TIMEOUT=3e3,Nn.RECONNECT_TIME_MAX=5,Nn.RECONNECT_SLEEP_TIME=1e3,Nn.CONTROL_HIDE_TIME=3e3,Nn.DBCLICK_TIME=300,Nn.DBCLICK_FULLSCREEN=!0,Nn.MOBILE_DBCLICK_PLAY=!0,Nn.MOBILE_CLICK_PLAY=!1,Nn.AUTO_ORIENTATION_TIME=200,Nn.INFO_LOOP_TIME=1e3,Nn.FAST_FORWARD_VALUE=3,Nn.FAST_FORWARD_TIME=1e3,Nn.TOUCH_MOVE_RATIO=.5,Nn.VOLUME_STEP=.1,Nn.SEEK_STEP=5,Nn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Nn.ASPECT_RATIO=["default","4:3","16:9"],Nn.FLIP=["normal","horizontal","vertical"],Nn.FULLSCREEN_WEB_IN_BODY=!0,Nn.LOG_VERSION=!0,Nn.USE_RAF=!1,Nn.REMOVE_SRC_WHEN_DESTROY=!0,_n=Nn,Wn=$n,$&&(window.Artplayer=_n,g("artplayer-style",Wn),setTimeout(()=>{_n.LOG_VERSION&&console.log(`%c ArtPlayer %c ${_n.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Nn}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var f=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const g=globalThis.CUSTOM_USER_AGENT,y=null!=g?g:"undefined"===typeof navigator?"":navigator.userAgent,b=/^(?:(?!chrome|android).)*safari/i.test(y),w=/iPad|iPhone|iPod/i.test(y)&&("undefined"===typeof window||!window.MSStream),x=w||y.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,k=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(y)||x,$="undefined"!==typeof window&&"undefined"!==typeof document;const E={properties:["audioTracks","autoplay","buffered","controller","controls","crossOrigin","currentSrc","currentTime","defaultMuted","defaultPlaybackRate","duration","ended","error","loop","mediaGroup","muted","networkState","paused","playbackRate","played","preload","readyState","seekable","seeking","src","startDate","textTracks","videoTracks","volume"],methods:["addTextTrack","canPlayType","load","play","pause"],events:["abort","canplay","canplaythrough","durationchange","emptied","ended","error","loadeddata","loadedmetadata","loadstart","pause","play","playing","progress","ratechange","seeked","seeking","stalled","suspend","timeupdate","volumechange","waiting"],prototypes:["width","height","videoWidth","videoHeight","poster","webkitDecodedFrameCount","webkitDroppedFrameCount","playsInline","webkitSupportsFullscreen","webkitDisplayingFullscreen","onenterpictureinpicture","onleavepictureinpicture","disablePictureInPicture","cancelVideoFrameCallback","requestVideoFrameCallback","getVideoPlaybackQuality","requestPictureInPicture","webkitEnterFullScreen","webkitEnterFullscreen","webkitExitFullScreen","webkitExitFullscreen"]};class A extends Error{constructor(t){super("Failed to release ArtPlayer resources"),this.errors=t,this.name="ResourceCleanupError"}}class C{constructor(){this.cleanups=new Set,this.disposed=!1}get closed(){return this.disposed}add(t){let e=!0;const r=()=>{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new C,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof A?t.push(...e.errors):t.push(e)}if(t.length)throw new A(t)}}const S=new WeakMap,T=new WeakMap;function L(t){const e=S.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function P(t){return L(t).scope}function M(t){const e=L(t);return e.destroying||e.scope.closed}function z(t,e,r,n,o=!1){var i,a,s;const l=L(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof A?e.errors:[e])}};n&&(null==(i=t.template)?void 0:i.$video)&&d(()=>t.reset()),d(()=>l.scope.dispose()),d(()=>{var e;return null==(e=t.template||l.mountingTemplate)?void 0:e.destroy(r)});const u=e.indexOf(t);-1!==u&&e.splice(u,1),t.isDestroy=!0,o||(null==(a=l.releaseContainer)||a.call(l),l.releaseContainer=void 0),d(()=>t.emit("destroy")),d(()=>l.finalizers.dispose()),o&&l.rollback&&d(l.rollback),l.rollback=void 0,null==(s=l.releaseContainer)||s.call(l),l.releaseContainer=void 0;for(const p of c.slice(1))console.warn("Additional ArtPlayer cleanup failure:",p);if(c.length)throw c[0]}const O=new WeakMap;function R(t,e){const r=P(t).child();return O.set(e,r),r}function D(t){const e=O.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function I(t){var e;null==(e=O.get(t))||e.dispose()}function N(t,e,r,n){const o=D(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function _(t,e){return{on:(r,n)=>{N(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=D(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}function W(t){var e;if(t.composedPath)return t.composedPath();const r=[];let n=t.target;for(;n;)r.push(n),n=null!=(e=n.parentNode)?e:null;return"undefined"===typeof window||r.includes(window)||r.push(window),r}function F(t,e){return W(t).includes(e)}function V(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function Y(t){return t.getBoundingClientRect()}function B(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;";try{document.body.appendChild(t);const e=getComputedStyle(t);return{top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0}}finally{t.remove()}}function H(t,e=document){return e.querySelector(t)}function j(t,e){return t.classList.add(e)}function q(t,e){return t.classList.remove(e)}function U(t,e){return t.classList.contains(e)}function X(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function G(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function K(t,e){G(t).forEach(t=>q(t,e)),j(t,e)}function Z(t,e){return e.parentNode.replaceChild(t,e),t}function J(t){return document.createElement(t)}function Q(t,e,r="top"){k||(t.setAttribute("aria-label",e),j(t,"hint--rounded"),j(t,`hint--${r}`))}function tt(t="",e=""){const r=J("i");return j(r,"art-icon"),j(r,`art-icon-${t}`),X(r,e),r}function et(t,e,r){return t.style[e]=r,t}function rt(t,e){for(const r in e)et(t,r,e[r]);return t}function nt(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new C;let a=!1,s=()=>{};function l(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function c(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void c(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;d(l,()=>c(l)),i.closed||(l.src=e)}catch(e){l(e)}}))}),i.closed||(n.src=t)}catch(u){l(u)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){l(u)}},e.onerror=()=>l(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}class ot extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function it(t,e){if(!t)throw new ot(e);return t}function at(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function st(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function lt(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function ct(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const pt={"&":"&","<":"<",">":">","'":"'",'"':"""},ft={"&":"&","<":"<",">":">","'":"'",""":'"'},ht=/(&|<|>|'|")/g;function mt(t){return t.replace(/[&<>'"]/g,t=>pt[t]||t)}const vt=Object.defineProperty,{hasOwnProperty:gt}=Object.prototype;function yt(t,e){return gt.call(t,e)}function bt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function wt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?wt(o,i):i,vt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function xt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function kt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function $t(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const Et=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:ot,addClass:j,append:X,assToVtt:$t,capitalize:dt,clamp:ct,createElement:J,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:vt,download:lt,errorHandle:it,escape:mt,get:bt,getComposedPath:W,getExt:st,getIcon:tt,getRect:Y,getSafeAreaInsets:B,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:U,includeFromEvent:F,inverseClass:K,isBrowser:$,isIOS:w,isIOS13:x,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:k,isSafari:b,loadImg:function(t,e){return nt(t,e,void 0)},mergeDeep:wt,query:H,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:q,replaceElement:Z,secondToTime:ut,setStyle:et,setStyleText:v,setStyles:rt,siblings:G,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:V,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:Q,unescape:function(t){return t.replace(ht,t=>ft[t]||t)},userAgent:y,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function At(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||(null==s?void 0:s.aborted))return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{null==s||s.removeEventListener("abort",l)}}),null==s||s.addEventListener("abort",l,{once:!0}),l}function Ct(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function St(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const Tt=new WeakSet;function Lt(t){Tt.add(t),t.preventDefault()}function Pt(t){return!t.altKey&&!t.ctrlKey&&!t.metaKey&&!t.isComposing&&229!==t.keyCode}function Mt(t,e,r=()=>e.click(),n=()=>!0){if(t.closed)return;e.hasAttribute("role")||e.setAttribute("role","button"),e.hasAttribute("tabindex")||(e.tabIndex=0);let o=!1;const i=()=>n()&&"true"!==e.getAttribute("aria-disabled")&&!e.hasAttribute("disabled"),a=t=>(t.composedPath()[0]||t.target)===e;At(t,e,"keydown",t=>{const e=t;a(e)&&Pt(e)&&!e.defaultPrevented&&("Enter"===e.key?(Lt(e),!e.repeat&&i()&&r()):" "===e.key&&(Lt(e),!e.repeat&&i()&&(o=!0)))}),At(t,e,"keyup",t=>{const n=t;if(" "!==n.key)return;const s=o;o=!1,s&&a(n)&&Pt(n)&&!n.defaultPrevented&&i()&&e.ownerDocument.activeElement===e&&(Lt(n),r())}),At(t,e,"blur",()=>{o=!1}),t.add(()=>{o=!1})}function zt(t,e){return X(t,e)}function Ot(t,e){return e.querySelector(t)}const Rt=new WeakSet;function Dt(t){const e=t.template.$player;!M(t)&&e.isConnected&&(e.hasAttribute("tabindex")||(e.setAttribute("tabindex","-1"),Rt.has(e)||(Rt.add(e),P(t).add(()=>{Rt.delete(e),"-1"===e.getAttribute("tabindex")&&e.removeAttribute("tabindex")}))),e.focus({preventScroll:!0}))}const It=new WeakSet,Nt="[tabindex],button,input,select,textarea,a[href],[contenteditable]";function _t(t){return[t,...t.querySelectorAll(Nt)].find(t=>{var e;if(!t.matches(Nt)||t.tabIndex<0||t.matches(":disabled")||t.closest("[inert]")||"true"===t.getAttribute("aria-disabled")||!t.getClientRects().length)return!1;const r=null==(e=t.ownerDocument.defaultView)?void 0:e.getComputedStyle(t);return"hidden"!==(null==r?void 0:r.visibility)&&"collapse"!==(null==r?void 0:r.visibility)})}function Wt(t,e,r){var n;const o=null==e?void 0:e.ownerDocument,i=null==o?void 0:o.activeElement;if(!["control","contextmenu"].includes(null!=(n=t.name)?n:"")||It.has(t)||!e||!o||!i||!e.contains(i))return()=>{};const a=t.art.template.$player,s=Array.from(a.querySelectorAll(`.art-${t.name}`)),l=s.indexOf(e),c=[...s.slice(l+1),...s.slice(0,l).reverse()];return It.add(t),()=>{var e;if(It.delete(t),M(t.art)||!a.isConnected||o.activeElement!==o.body)return;const n=r?null==(e=t.cache.get(r))?void 0:e.$ref:void 0;for(const t of[...n?[n]:[],...c]){if(!a.contains(t))continue;const e=_t(t);if(e)return void e.focus({preventScroll:!0})}Dt(t.art)}}const Ft="array",Vt="boolean",Yt="string",Bt="number",Ht="object",jt="function";function qt(t,e,r){return it(e===Yt||e===Bt||t instanceof Element,`${r.join(".")} require '${Yt}' or 'Element' type`)}const Ut={html:qt,disable:`?${Vt}`,name:`?${Yt}`,index:`?${Bt}`,style:`?${Ht}`,click:`?${jt}`,mounted:`?${jt}`,tooltip:`?${Yt}|${Bt}`,width:`?${Bt}`,selector:`?${Ft}`,onSelect:`?${jt}`,switch:`?${Vt}`,onSwitch:`?${jt}`,range:`?${Ft}`,onRange:`?${jt}`,onChange:`?${jt}`},Xt={id:Yt,container:qt,url:Yt,poster:Yt,type:Yt,theme:Yt,lang:Yt,volume:Bt,isLive:Vt,muted:Vt,autoplay:Vt,autoSize:Vt,autoMini:Vt,loop:Vt,flip:Vt,playbackRate:Vt,aspectRatio:Vt,screenshot:Vt,setting:Vt,hotkey:Vt,pip:Vt,mutex:Vt,backdrop:Vt,fullscreen:Vt,fullscreenWeb:Vt,subtitleOffset:Vt,miniProgressBar:Vt,useSSR:Vt,playsInline:Vt,lock:Vt,gesture:Vt,fastForward:Vt,autoPlayback:Vt,autoOrientation:Vt,airplay:Vt,proxy:`?${jt}`,plugins:[jt],layers:[Ut],contextmenu:[Ut],settings:[Ut],controls:[l(s({},Ut),{position:(t,e,r)=>{const n=["top","left","right"];return it("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${Vt}`,html:Yt,url:Yt}],highlight:[{time:Bt,text:Yt}],thumbnails:{url:Yt,number:Bt,column:Bt,width:Bt,height:Bt,scale:Bt},subtitle:{url:Yt,name:Yt,type:Yt,style:Ht,escape:Vt,encoding:Yt,onVttLoad:jt},moreVideoAttr:Ht,i18n:Ht,icons:Ht,cssVar:Ht,customType:Ht},Gt=new WeakSet;class Kt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return U(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?j(e,r):q(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(M(this.art))return;const r="function"===typeof t?t(this.art):t;if(M(this.art))return;if(r.html=r.html||"",h(r,Ut),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;it(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=R(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,n);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){j(t,`art-${r}`),j(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):X(e,t),i.html&&X(t,i.html),i.style&&rt(t,i.style),i.tooltip&&Q(t,i.tooltip)}(i,this.$parent,this.name,n,this.id,r),a.closed)return;if(r.click){("control"===this.name&&!r.selector||"contextmenu"===this.name&&!i.querySelector("[data-value]"))&&!i.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")&&Mt(a,i);const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),r.click.call(this.art,this,t))});s.push(t)}if(r.selector&&["left","right"].includes(r.position)&&this.selector(r,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,n,i),c=!0,o.set(n,{$ref:i,events:s,option:r}),r.mounted&&r.mounted.call(this.art,i),i}catch(d){try{I(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw(null==(e=o.get(n))?void 0:e.$ref)===i&&o.delete(n),c&&this[n]===i&&(l?Object.defineProperty(this,n,l):delete this[n]),i.remove(),d}}remove(t){it(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(Gt.has(e))return;const r=Wt(this,e.$ref);Gt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{I(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Gt.delete(e),r()}}update(t){var e;const r=Wt(this,null==(e=this.cache.get(t.name))?void 0:e.$ref,t.name);try{if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}finally{r()}}}function Zt(t){for(const e of t.querySelectorAll("[data-value]"))e.setAttribute("aria-pressed",String(e.classList.contains("art-current")))}function Jt(t,e){var r,n;const o=D(t);if(!o.closed){t.setAttribute("role","group"),t.setAttribute("aria-label",e);for(const i of t.querySelectorAll("[data-value]"))Mt(o,i),i.setAttribute("aria-label",`${e}: ${null!=(n=null==(r=i.textContent)?void 0:r.trim())?n:""}`);Zt(t)}}const Qt=new WeakMap;function te(t,e){e?Qt.set(t,e):Qt.delete(t)}function ee(t){const e=new Set;let r=t;for(;!e.has(r);){e.add(r);let t,n=r;for(;n&&!t;)t=Qt.get(n),n=n.parentElement;if(!t)return r;r=t}return t}function re(t){const e=t;return!!e&&(["INPUT","TEXTAREA","SELECT"].includes(e.tagName)||e.isContentEditable)}function ne(t){var e;const r=null==(e=t.ownerDocument.defaultView)?void 0:e.getComputedStyle(t).visibility;return t.isConnected&&!t.matches(":disabled")&&!t.closest("[inert]")&&"true"!==t.getAttribute("aria-disabled")&&t.getClientRects().length>0&&"hidden"!==r&&"collapse"!==r}class oe extends Kt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,R(t,this.$parent),k||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=_(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join(""),i=r.get("Play Speed");return l(s({},t),{html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=_(e,t),n=H('[data-value="1"]',t);n&&K(n,"art-current"),Jt(t,i),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&(K(r,"art-current"),Zt(t))})}})}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join(""),i=r.get("Aspect Ratio");return l(s({},t),{html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=_(e,t),n=H('[data-value="default"]',t);n&&K(n,"art-current"),Jt(t,i),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&(K(r,"art-current"),Zt(t))})}})}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(dt(t))}`).join(""),i=r.get("Video Flip");return l(s({},t),{html:`${i}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=_(e,t),n=H('[data-value="normal"]',t);n&&K(n,"art-current"),Jt(t,i),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&(K(r,"art-current"),Zt(t))})}})}}({name:"flip",index:30})),this.add(function(t){return e=>l(s({},t),{html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return l(s({},t),{html:`ArtPlayer ${m}`})}({name:"version",index:50})),this.add(function(t){return e=>l(s({},t),{html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let s=0;s{this.show=!0,i.closed||M(this.art)||!this.show||function(t,e,r){const{$player:n,$contextmenu:o}=t.template,{height:i,width:a,left:s,top:l}=Y(n),{height:c,width:d}=Y(o);let u=e-s,p=r-l;e+d>s+a&&(u=a-d),r+c>l+i&&(p=i-c),M(t)||rt(o,{top:`${p}px`,left:`${u}px`})}(this.art,t,e)},c=function(t,e){const{art:r}=t,{$player:n,$contextmenu:o}=r.template,i=D(o),a=()=>!i.closed&&!M(r);let s,l=!1,c="",d=0;const u=()=>{const t=n.ownerDocument.activeElement;s=t&&n.contains(t)?ee(t):n,te(o,s)},p=()=>Array.from(o.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]")).filter(t=>t.tabIndex>=0&&ne(t)),f=r.i18n.get("Context Menu");if(!a())return{pointer:()=>!1};o.setAttribute("role","group"),o.setAttribute("aria-label",f);const h=t=>{if(!a())return;if(t)return void(o.contains(n.ownerDocument.activeElement)||u());const e=n.ownerDocument.activeElement,i=o.contains(e)||l&&e===n.ownerDocument.body,d=s;s=void 0,l=!1,c="",te(o),i&&(d&&n.contains(d)&&ne(d)&&d.focus({preventScroll:!0}),(n.ownerDocument.activeElement===n.ownerDocument.body||o.contains(n.ownerDocument.activeElement))&&Dt(r))};r.on("contextmenu",h),i.add(()=>{r.off("contextmenu",h),te(o)}),At(i,o,"focusin",()=>{l=!0});let m=!1;return At(i,o,"focusout",e=>{o.contains(e.relatedTarget)||m||(m=!0,Ct(i,()=>{m=!1,a()&&t.show&&!o.contains(n.ownerDocument.activeElement)&&(t.show=!1)},0))}),At(i,n,"keydown",n=>{var i;const s=n;if(!a()||!Pt(s)||s.defaultPrevented)return;if(("ContextMenu"===s.key||"F10"===s.key&&s.shiftKey)&&r.constructor.CONTEXTMENU&&!re(s.target)){Lt(s),u();const r=s.target.getBoundingClientRect();return e(r.left,r.bottom),void(a()&&t.show&&(null==(i=p()[0])||i.focus({preventScroll:!0})))}if(!t.show||!o.contains(s.target))return;if("Escape"===s.key)return Lt(s),void(t.show=!1);if("Tab"===s.key)return void(t.show=!1);if(re(s.target))return;const l=p(),f=l.indexOf(s.target);let h;if("ArrowDown"===s.key||"ArrowRight"===s.key)h=l[(f+1)%l.length];else if("ArrowUp"===s.key||"ArrowLeft"===s.key)h=l[(f+l.length-1)%l.length];else if("Home"===s.key)h=l[0];else if("End"===s.key)h=l[l.length-1];else{if(1!==s.key.length||" "===s.key)return;{const t=s.key.toLowerCase();c=Date.now()-d>700?t:c+t,d=Date.now();const e=[...c].every(e=>e===t)?t:c;h=[...l.slice(f+1),...l.slice(0,f+1)].find(t=>(t.getAttribute("aria-label")||t.textContent||"").trim().toLowerCase().startsWith(e))}}Lt(s),null==h||h.focus({preventScroll:!0})}),{pointer:t=>!(!a()||!r.constructor.CONTEXTMENU||re(t.target))&&(u(),!0)}}(this,a);o(e,"contextmenu",t=>{c.pointer(t)&&(t.preventDefault(),a(t.clientX,t.clientY))}),o(e,"click",t=>{F(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}const ie=new WeakMap,ae=new WeakMap,se=new WeakMap;function le(t){return se.get(t)||P(t)}function ce(t){const e=ie.get(t),r=se.get(t);return()=>ie.get(t)===e&&(!e||e.active())&&se.get(t)===r&&(!r||!r.closed)}function de(t){const e=se.get(t),r=P(t).child(),n=r.child();se.set(t,r),r.add(()=>{se.get(t)===r&&se.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!M(t)&&!n.closed&&ie.get(t)===o};return ie.set(t,o),n.add(()=>{ie.get(t)===o&&ie.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function ue(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function pe(t,e,r){ae.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{ae.get(t)===e&&(ae.delete(t),ue(e))}}function fe(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function he(t,e){const{$progress:r}=t.template,{left:n}=Y(r),o=ct((k?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:ut(i),width:o,percentage:ct(o/r.clientWidth,0,1)}}function me(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=he(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}const ve=new Map([["ArrowRight",1],["ArrowUp",1],["ArrowLeft",-1],["ArrowDown",-1],["PageUp",10],["PageDown",-10]]);function ge(t,e,r,n,o,i="horizontal"){const a=t=>[t.min,t.max,t.value,t.step].every(Number.isFinite)&&t.max>t.min&&t.step>0,s=(t,e)=>Math.min(e.max,Math.max(e.min,t)),l=()=>{if(t.closed)return;const r=n(),o=a(r),i=o?s(r.value,r):0;e.setAttribute("aria-disabled",String(!o)),e.setAttribute("aria-valuemin",String(o?r.min:0)),e.setAttribute("aria-valuemax",String(o?r.max:0)),e.setAttribute("aria-valuenow",String(i)),e.setAttribute("aria-valuetext",r.text(i))};return t.closed||(e.setAttribute("role","slider"),e.tabIndex=0,e.setAttribute("aria-label",r),e.setAttribute("aria-orientation",i),At(t,e,"keydown",t=>{const r=t;if((r.composedPath()[0]||r.target)!==e||!Pt(r)||r.defaultPrevented)return;const i=ve.get(r.key);if(void 0===i&&"Home"!==r.key&&"End"!==r.key)return;Lt(r);const c=n();if(!a(c))return void l();const d="Home"===r.key?c.min:"End"===r.key?c.max:s(c.value,c)+i*c.step;o(s(d,c)),l()}),l()),l}const ye=new WeakMap;function be(t){return ye.get(t)||0}function we(t,e,r){let n,o=!1,i=!1,a=!1,s=be(t);const l=()=>a||be(t)!==s,c=()=>{var e,r;return!!(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)};return{restore(i=()=>{t.currentTime=e}){if(!r()||l())return;const d=be(t);i(),s=be(t),s>d+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}function xe(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=D(e),{on:a}=_(t,e);let s=()=>{};const l=Ot(".art-progress-hover",e),c=Ot(".art-progress-loaded",e),d=Ot(".art-progress-played",e),u=Ot(".art-progress-highlight",e),p=Ot(".art-progress-indicator",e),f=Ot(".art-progress-tip",e);function h(r,n){const{width:o,time:i}=n||he(t,r);f.textContent=i||"00:00";const a=f.clientWidth;o<=a/2?et(f,"left",0):o>e.clientWidth-a/2?et(f,"left",e.clientWidth-a+"px"):et(f,"left",o-a/2+"px")}r.indicator?X(p,r.indicator):et(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&k;if("loaded"===r&&et(c,"width",100*n+"%"),"hover"===r&&(et(l,"width",100*n+"%"),F(a,u)?function(r){const{width:n}=he(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;f.textContent=null!=o?o:"";const i=f.clientWidth;n<=i/2?et(f,"left",0):n>e.clientWidth-i/2?et(f,"left",e.clientWidth-i+"px"):et(f,"left",n-i/2+"px")}(a):h(a),0===n?q(o,"art-progress-hover"):j(o,"art-progress-hover")),"played"===r&&(et(d,"width",100*n+"%"),et(p,"left",100*n+"%")),m){j(o,"art-progress-hover");h(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Ct(i,()=>{q(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function ke(t){return e=>l(s({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{xe(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=_(t,e),a=D(e);let s=0;const l=()=>{const e=ce(t);return()=>!a.closed&&!M(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!k){let e;i(r,"click",e=>{e.target!==n&&me(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=he(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(null==n?void 0:n()){const{second:o,percentage:i}=he(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t),function(t,e){const r=D(e),{on:n}=_(t,e);let o,i=0;const a=ge(r,e,t.i18n.get("Progress"),()=>({min:0,max:t.duration,value:t.currentTime,step:t.constructor.SEEK_STEP,text:e=>`${ut(e)} / ${ut(Number.isFinite(t.duration)&&t.duration>0?t.duration:0)}`}),e=>{const n=++i;null==o||o.dispose();const s=r.child();o=s;const l=le(t).add(()=>{s.dispose()});s.add(()=>{l()}),s.add(()=>{o===s&&(o=void 0)});const c=ce(t),d=()=>n===i&&!s.closed&&!M(t)&&c(),u=we(t,e,d),p=()=>{d()?u.ready()&&(s.dispose(),a()):s.dispose()};for(const r of["video:seeked","video:ended"])t.on(r,p),s.add(()=>{t.off(r,p)});try{t.emit("setBar","played",e/t.duration),d()&&u.restore(()=>{t.seek=e}),p()}catch(f){throw s.dispose(),f}});n("video:loadedmetadata",a),n("video:durationchange",a),n("video:emptied",a),n("video:timeupdate",a),n("video:seeking",a),n("video:seeked",a),n("video:ended",a)}(e,t)}})}function $e(t){const{option:e}=t.art;e.isLive||t.add(ke({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>l(s({},t),{mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e,a=zt(t,o.play),s=zt(t,o.pause);function l(){t.setAttribute("aria-label",i.get("Play")),et(a,"display","flex"),et(s,"display","none")}function c(){t.setAttribute("aria-label",i.get("Pause")),et(a,"display","none"),et(s,"display","flex")}Mt(D(t),t,()=>(e.playing?s:a).click()),Q(a,i.get("Play")),Q(s,i.get("Pause")),n(a,"click",()=>{at(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>l(s({},t),{mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e,a=zt(t,o.volume),s=zt(t,o.volumeClose);for(const e of[a,s])Mt(D(t),e),e.setAttribute("aria-label",i.get("Mute"));const l=zt(t,'
'),c=zt(l,'
'),d=zt(c,'
'),u=zt(c,'
'),p=zt(u,'
'),f=zt(p,'
'),h=zt(u,'
'),m=D(t);let v=0;const g=ge(m,u,i.get("Volume"),()=>({min:0,max:100,value:e.muted?0:100*e.volume,step:100*e.constructor.VOLUME_STEP,text:t=>`${Math.round(t)}%`}),t=>{const r=++v;e.muted=!1,r!==v||m.closed||M(e)||(e.volume=t/100)},"vertical");function y(t){const{top:e,height:r}=Y(u);return 1-(t.clientY-e)/r}function b(){g();const r=t.ownerDocument.activeElement,n=e.muted||0===e.volume,o=n?s:a;if(a.setAttribute("aria-pressed",String(e.muted)),s.setAttribute("aria-pressed",String(e.muted)),n)et(a,"display","none"),et(s,"display","flex"),et(h,"top","100%"),et(f,"top","100%"),d.textContent="0";else{const t=100*e.volume;et(a,"display","flex"),et(s,"display","none"),et(h,"top",100-t+"%"),et(f,"top",100-t+"%"),d.textContent=String(Math.floor(t))}r!==a&&r!==s||r===o||o.focus({preventScroll:!0})}if(b(),r("video:volumechange",b),n(a,"click",()=>{e.muted=!0}),n(s,"click",()=>{e.muted=!1}),k)et(l,"display","none");else{let t=!1;n(u,"mousedown",r=>{t=0===r.button,e.volume=y(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=y(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>l(s({},t),{style:k?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=_(e,t);function n(){const r=`${ut(e.currentTime)} / ${ut(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!P(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!k&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=_(e,t),{icons:n}=e;Mt(D(t),t),zt(t,n.screenshot),r(t,"click",()=>{at(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e;zt(t,o.setting),Mt(D(t),t),t.setAttribute("aria-expanded","false"),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{t.setAttribute("aria-expanded",String(e)),Q(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e;Mt(D(t),t),zt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{Q(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=_(e,t),{icons:n}=e;Mt(D(t),t),zt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e;Mt(D(t),t);const a=zt(t,o.fullscreenWebOn),s=zt(t,o.fullscreenWebOff);et(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(Q(t,i.get("Exit Web Fullscreen")),et(a,"display","none"),et(s,"display","inline-flex")):(Q(t,i.get("Web Fullscreen")),et(a,"display","inline-flex"),et(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>l(s({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=_(e,t),{icons:o,i18n:i}=e;Mt(D(t),t);const a=zt(t,o.fullscreenOn),s=zt(t,o.fullscreenOff);et(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(Q(t,i.get("Exit Fullscreen")),et(a,"display","none"),et(s,"display","inline-flex")):(Q(t,i.get("Fullscreen")),et(a,"display","inline-flex"),et(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rCe.get(t).option.selector}),vt(t,"$control_item",{get:()=>Ce.get(t).item}),vt(t,"$control_value",{get:()=>Ce.get(t).value})),Ce.set(t,e)}function Te(t,e){t.innerHTML=e}function Le(t,e,r,n,o){const{proxy:i}=t.events,a=D(n),s=r.selector;j(n,"art-control-selector");const l=document.createElement("div");j(l,"art-selector-value"),X(l,r.html),n.textContent="",X(n,l);const d=zt(n,'
');for(let c=0;cc(null,null,function*(){var o,i;if(a.closed)return;const s=W(n),c=r.selector.find(t=>s.includes(t.$control_item));if(!c)return;const d=++u,p=()=>!a.closed&&d===u,f=a.add(function(t,e){return Ee.set(t,e),()=>{Ee.get(t)===e&&Ee.delete(t)}}(n,p));try{if(e(c),a.closed)return;if(r.onSelect){const e=yield r.onSelect.call(t,c,c.$control_item,n);if(p()){const t=l.contains(l.ownerDocument.activeElement);Te(l,e),null==(i=null==(o=Ce.get(c))?void 0:o.refresh)||i.call(o,t)}}}catch(h){console.warn("ArtPlayer selector failed:",h)}finally{f()}}));o.push(p);const f=function(t,e,r,n,o){if(t.closed)return()=>{};const i=Array.from(n.children),a=i.some(t=>t.querySelector(Ae));n.setAttribute("role",a?"group":"listbox"),n.setAttribute("aria-label",o);let s=!1,l=!1,c=!1,d="",u=0;const p=()=>i.length>0&&(l||s&&!c),f=()=>r.querySelector('button,a[href],[role="button"]')||r,h=(e=!1)=>{if(t.closed)return;const n=f();r.querySelector(Ae)?(r.removeAttribute("role"),r.removeAttribute("tabindex")):(r.setAttribute("role","button"),r.tabIndex=0),n!==r&&(r.removeAttribute("aria-haspopup"),r.removeAttribute("aria-expanded"),r.removeAttribute("aria-disabled")),a?n.removeAttribute("aria-haspopup"):n.setAttribute("aria-haspopup","listbox"),n.setAttribute("aria-expanded",String(p())),n.setAttribute("aria-disabled",String(0===i.length)),e&&r.isConnected&&r.ownerDocument.activeElement===r.ownerDocument.body&&n.focus({preventScroll:!0})},m=(t,r=!1)=>{l=t,c=r,e.classList.toggle("art-selector-open",t),e.classList.toggle("art-selector-dismissed",r),h()},v=e=>{e&&!t.closed&&((e.querySelector(Ae)||e).focus({preventScroll:!0}),t.closed||e.scrollIntoView({block:"nearest",inline:"nearest"}))},g=(e=!1)=>{!t.closed&&i.length&&(m(!0),d="",v(i.find(t=>t.classList.contains("art-current"))||i[e?i.length-1:0]))},y=()=>{if(t.closed)return;const o=n.contains(e.ownerDocument.activeElement);m(!1,!0),d="",o&&r.isConnected&&f().focus({preventScroll:!0})};Mt(t,r,()=>{r.click(),e.ownerDocument.activeElement===r&&g()}),h();for(const b of i){const e=b.classList.contains("art-current");a?b.setAttribute("aria-current",String(e)):(b.setAttribute("role","option"),b.setAttribute("aria-selected",String(e))),b.querySelector(Ae)||(b.tabIndex=-1,Mt(t,b,()=>{b.click(),y()}))}return At(t,r,"keydown",t=>{const e=t;!Pt(e)||e.defaultPrevented||e.target!==r&&e.target!==f()||("ArrowDown"===e.key||"ArrowUp"===e.key?(Lt(e),g("ArrowUp"===e.key)):"Escape"===e.key&&p()&&(Lt(e),y()))}),At(t,r,"click",t=>{t.isTrusted&&0===t.detail&&f()!==r&&g()}),At(t,n,"keydown",t=>{var e;const r=t;if(!Pt(r)||r.defaultPrevented)return;if("Escape"===r.key)return Lt(r),void y();const n=i.indexOf(r.target);if(n<0)return;let o;switch(1!==r.key.length&&(d=""),r.key){case"ArrowDown":o=Math.min(n+1,i.length-1);break;case"ArrowUp":o=Math.max(n-1,0);break;case"Home":o=0;break;case"End":o=i.length-1;break;case"ArrowLeft":case"ArrowRight":return void Lt(r);default:{if(1!==r.key.length||" "===r.key)return;const t=Date.now();d=t-u<500?d+r.key.toLocaleLowerCase():r.key.toLocaleLowerCase(),u=t;const a=[...d].every(t=>t===d[0])?d[0]:d;for(let r=1;r<=i.length;r++){const t=(n+r)%i.length;if(null==(e=i[t].textContent)?void 0:e.trim().toLocaleLowerCase().startsWith(a)){o=t;break}}}}Lt(r),void 0!==o&&v(i[o])}),At(t,n,"click",t=>{t.isTrusted&&0===t.detail&&y()}),At(t,e,"mouseenter",()=>{s=!0,m(l)}),At(t,e,"mouseleave",()=>{s=!1,m(n.contains(e.ownerDocument.activeElement))}),At(t,e,"focusout",t=>{e.contains(t.relatedTarget)||m(!1,!0)}),t.add(()=>{e.classList.remove("art-selector-open","art-selector-dismissed")}),h}(a,n,l,d,String(r.tooltip||r.name||l.textContent||t.i18n.get("Open")));for(const c of s)Ce.get(c).refresh=f}class Pe extends Kt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template,o=function(t,e,r){let n,o,i=!0;const a=()=>!t.closed&&i&&e.contains(e.ownerDocument.activeElement),s=()=>{const t=a(),n=e.classList.contains("art-keyboard-focus");e.classList.toggle("art-keyboard-focus",t),t&&!n&&r()},l=()=>{i=!0,s()},c=()=>{i=!1,s()},d=()=>{n!==e.ownerDocument&&(null==o||o.dispose(),n=e.ownerDocument,o=t.child(),At(o,n,"keydown",l,{capture:!0}),At(o,n,"mousedown",c,{capture:!0}),At(o,n,"touchstart",c,{capture:!0,passive:!0}))};return d(),At(t,e,"keydown",l,{capture:!0}),At(t,e,"mousedown",c,{capture:!0}),At(t,e,"touchstart",c,{capture:!0,passive:!0}),At(t,e,"focusin",()=>{d(),s()}),At(t,e,"focusout",()=>{e.classList.remove("art-keyboard-focus")}),t.add(()=>{e.classList.remove("art-keyboard-focus")}),a}(R(t,n),r,()=>{this.show=!0}),{on:i,proxy:a}=_(t,n);a(r,"focusin",e=>{var r;t.isFocus=!0,t.isInput="INPUT"===(null==(r=e.target)?void 0:r.tagName)}),a(r,"focusout",e=>{r.contains(e.relatedTarget)||(t.isFocus=!1,t.isInput=!1)}),i("mousemove",()=>{k||(this.show=!0)}),i("click",()=>{k?this.toggle():this.show=!0}),i("document:mousemove",t=>{this.isHover=F(t,n)}),i("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&!o()&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),i("control",t=>{t?(q(r,"art-hide-cursor"),j(r,"art-hover"),this.timer=Date.now()):(j(r,"art-hide-cursor"),q(r,"art-hover"))}),this.init(),P(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=D(e),{on:i}=_(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){$e(this)}add(t){if(M(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:it(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){var e,r;if(!t)return;const n=t.$control_value.contains(t.$control_value.ownerDocument.activeElement);Te(t.$control_value,t.html);for(let o=0;othis.check(t),t,e,r)}}function Me(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(M(t))return;const o=F(r,e);t.isInput=o&&"INPUT"===(null==(n=r.target)?void 0:n.tagName),t.isFocus=o,t.emit(o?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),P(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(M(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),M(t))return;(!k||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),M(t))return;k?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function ze(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!M(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),P(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(M(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:ce(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{me(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=ct((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=ct(i.time+t.duration*d*l,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",ct(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${ut(u)} / ${ut(t.duration)}`))},cancel:r}}const Oe=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],Re=["resize","scroll","orientationchange"];const De=new WeakMap;function Ie(t){const e=De.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function Ne(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=Ne(t,e,r,n,o);return i.push(a),a})}catch(f){for(const t of i.reverse())try{t()}catch(h){console.warn("Failed to roll back event listener:",h)}throw f}}const i=r,a=Ie(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(null==o?void 0:o.capture),once:Boolean(null==o?void 0:o.once),passive:null==o?void 0:o.passive,signal:null==o?void 0:o.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||(null==c?void 0:c.aborted))return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,l),null==c||c.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):(null==c?void 0:c.aborted)?p():null==c||c.addEventListener("abort",p,{once:!0})}catch(f){try{u(!0)}catch(h){console.warn("Failed to roll back event listener:",h)}throw f}return p}function _e(t){return(e,r)=>{if(M(t))return;const n=(...e)=>{if(!M(t))return r(...e)};t.on(e,n),P(t).add(()=>{t.off(e,n)})}}function We(t){if(!t.constructor.USE_RAF)return;const e=P(t);let r=()=>{};const n=()=>{M(t)||(t.playing&&t.emit("raf"),M(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),_e(t)("destroy",()=>r())}class Fe{constructor(t){this.destroyEvents=new Set,function(t,e){De.set(t,{scope:P(e),cleaning:!1})}(this,t),P(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Me(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{M(t)||(j(r,"art-hover"),t.emit("hover",!0,e))},e=>{M(t)||(q(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{M(t)||t.emit("mousemove",e)})}(t,this),function(t,e){var r,n;const{option:o,constructor:i}=t,a=_e(t);a("resize",()=>{const{aspectRatio:e,notice:r}=t;"standard"===t.state&&o.autoSize&&t.autoSize(),M(t)||(t.aspectRatio=e,M(t)||(r.show=""))});const s=P(t);let l=()=>{};const c=()=>{M(t)||(l(),l=Ct(s,()=>t.emit("resize"),i.RESIZE_TIME))};a("window:orientationchange",c),a("window:resize",c);const d=null==(n=null==(r=t.template.$player.ownerDocument.defaultView)?void 0:r.screen)?void 0:n.orientation;"function"===typeof(null==d?void 0:d.addEventListener)&&e.proxy(d,"change",c)}(t,this),function(t,e){if(!k||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=ze(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=P(t),a=_e(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=(null==o?void 0:o.innerHeight)||n.documentElement.clientHeight,a=(null==o?void 0:o.innerWidth)||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),M(t)||(s=!0,Ct(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;P(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){var a;if(M(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||M(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,s=i.window||(null==(a=n.ownerDocument)?void 0:a.defaultView)||window,d=(n,o,i)=>{for(const a of o){if(c())return;l.disposers.push(e.proxy(n,a,e=>{r!==l||M(t)||t.emit(`${i}:${a}`,e)}))}};d(o,Oe,"document"),d(s,Re,"window")}catch(u){throw o(l),u}if(c())return void o(l);const d=r;r=l,o(d)}i(),e.bindGlobalEvents=i}(t,this),We(t)}proxy(t,e,r,n={}){return Array.isArray(e),Ne(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=Ie(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function Ve(t){if(t&&1===t.nodeType)return t}function Ye(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}function Be(t,e){var r,n,o,i;if(function(t){return Tt.has(t)}(t)||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const a=function(t,e){var r;const n=t.target;return 9===(null==n?void 0:n.nodeType)?n:(null==n?void 0:n.ownerDocument)||(null==(r=t.view)?void 0:r.document)||e}(t,e);let s=Ve(a.activeElement);for(;null==(r=null==s?void 0:s.shadowRoot)?void 0:r.activeElement;)s=Ve(s.shadowRoot.activeElement);if(s&&Ye(s))return!1;const l=Ve(null==(n=t.composedPath)?void 0:n.call(t)[0])||Ve(t.target),c="Enter"===t.key||"Enter"===t.code||"NumpadEnter"===t.code;if(c||" "===t.key||"Space"===t.code){const t='button,summary,[role="button"],[role="switch"]'+(c?",a[href]":"");if((null==(o=null==l?void 0:l.closest)?void 0:o.call(l,t))||(null==(i=null==s?void 0:s.closest)?void 0:i.call(s,t)))return!1}return!l||!Ye(l)}const He=new WeakMap;class je{constructor(t){this.art=t,this.keys={},He.set(this,{subscribed:!1}),k||this.init()}init(){const t=this.art;if(M(t))return;const e=He.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{at(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!M(t)){if(t.isFocus&&Be(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const qe={"Context Menu":"\u5feb\u6377\u83dc\u5355",Lock:"\u9501\u5b9a",Back:"\u8fd4\u56de",Settings:"\u8bbe\u7f6e",Progress:"\u64ad\u653e\u8fdb\u5ea6","Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",qe);class Ue{constructor(t){this.art=t,this.languages={"zh-cn":qe},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=yt(this.languages,t)&&this.languages[t]||{}}get(t){return yt(this.language,t)&&this.language[t]||t}update(t){this.languages=wt(this.languages,t),this.init()}}const Xe={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class Ge{constructor(t){const e=s(s({},Xe),t.option.icons);for(const r in e)vt(this,r,{get:()=>tt(r,e[r])})}}const Ke=new WeakMap;function Ze(t,e,r){const n=()=>!e.closed&&!M(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)}),function(t,e,r){const{$player:n,$info:o,$infoClose:i}=t.template;if(!o)return;const a=()=>!e.closed&&!M(t),s=()=>n.classList.contains("art-info-show"),l=t.i18n.get("Close");if(!a())return;const c=t.i18n.get("Video Info");if(!a())return;i.setAttribute("aria-label",l),o.setAttribute("role","group"),o.setAttribute("aria-label",c),Mt(e,i,()=>i.click(),s),At(e,o,"keydown",t=>{const e=t;a()&&s()&&Pt(e)&&!e.defaultPrevented&&"Escape"===e.key&&(Lt(e),r())});const d=e=>{var r;if(!a())return;const s=n.ownerDocument,l=s.activeElement;if(e)o.contains(l)||(Ke.delete(t),l&&n.contains(l)&&(Ke.set(t,ee(l)),n.classList.contains("art-keyboard-focus")&&i.focus({preventScroll:!0})));else{const e=Ke.get(t);if(Ke.delete(t),!o.contains(l))return;const i=e&&(null==(r=s.defaultView)?void 0:r.getComputedStyle(e).visibility);(null==e?void 0:e.isConnected)&&n.contains(e)&&e.getClientRects().length&&"hidden"!==i&&"collapse"!==i&&!e.matches(":disabled")&&!e.closest("[inert]")&&"true"!==e.getAttribute("aria-disabled")?e.focus({preventScroll:!0}):Dt(t)}};t.on("info",d),e.add(()=>{t.off("info",d)})}(t,e,r);const f=()=>{var t;try{for(const e of u){if(!n())return;const r=Reflect.get(c,null!=(t=e.dataset.video)?t:"undefined");if(!n())return;const o="number"===typeof r?r.toFixed(2):r;if(!n())return;if(e.textContent!==o){const t=null==o?null:`${o}`;if(!n())return;e.textContent=t}}n()&&Ct(e,f,a.INFO_LOOP_TIME)}catch(r){o(r)}};n()&&f()}catch(i){o(i)}}const Je=new WeakMap;class Qe extends Kt{constructor(t){super(t),this.name="info",Je.set(this,{revision:0}),k||this.init()}init(){var t;const e=Je.get(this),r=++e.revision;if(null==(t=e.scope)||t.dispose(),M(this.art)||e.revision!==r)return;const n=P(this.art).child();e.scope=n,n.add(()=>{e.scope===n&&(e.scope=void 0)}),Ze(this.art,n,()=>{this.show=!1})}}class tr extends Kt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{et(i,"display","none"),et(s,"display",null),M(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,L(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),M(t)||n.proxy(e.$state,"click",()=>{M(t)||at(t.play())})}}const nr=new WeakMap;function or(t){const e=nr.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class ir{constructor(t){this.art=t,this.timer=null,nr.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),P(t).add(()=>{t.off("destroy",e)}),P(t).add(()=>{this.destroy()})}destroy(){or(this)}set show(t){if(M(this.art))return;const e=nr.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){or(this);const i=e.revision,a=()=>!M(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(j(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(M(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",M(this.art)||e.revision!==t||q(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else q(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function ar(t,e){return function(t,e){const r=wt(e,t);return r.container=t.container,h(r,Xt)}(t,e)}function sr({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function lr(t,e){if(!sr(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return sr(r)?r:void 0}function cr(t,e,r,n=!1){const o=e=>{M(t)||r(e)};t[n?"once":"on"](e,o),P(t).add(()=>{t.off(e,o)})}function dr(t,e,r){for(const[n,o]of e){if(M(t)||r&&!r())return;t[n].show=o}}function ur(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=le(t),l=0;return{reset(){l=0,null==a||a.dispose(),q(i,"art-error")},loadStart(){q(i,"art-error")},schedule(d){(d=>c(null,null,function*(){if(M(t))return;const c=le(t);if(c!==s&&(s=c,l=0),a&&!a.closed)return;const u=c.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!M(t)&&!u.closed&&c===le(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}const pr=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],fr=(()=>{if("undefined"===typeof document)return!1;const t=pr[0],e={};for(const r of pr){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),hr={change:fr.fullscreenchange,error:fr.fullscreenerror},mr={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{mr.off("change",o),r()};mr.on("change",o);const i=t[fr.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!mr.isFullscreen)return void t();const r=()=>{mr.off("change",r),t()};mr.on("change",r);const n=document[fr.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>mr.isFullscreen?mr.exit():mr.request(t,e),onchange(t){mr.on("change",t)},onerror(t){mr.on("error",t)},on(t,e){const r=hr[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=hr[t];r&&document.removeEventListener(r,e,!1)},raw:fr};function vr(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(mr,{isFullscreen:{get:()=>Boolean(document[fr.fullscreenElement])},element:{enumerable:!0,get:()=>document[fr.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[fr.fullscreenEnabled])}});const gr=new WeakMap;function yr(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function br(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=gr.get(t);if(!n){n=new WeakMap,gr.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),yr(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),yr(i))}function wr(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,u=!1,p=!1;const f=new Promise((t,e)=>{a=t,s=e});function h(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!u&&r&&br(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&h()};if(At(i,t.document,t.changeEvent,m),At(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&h(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){var e;null==(e=gr.get(t.document))||e.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,c&&!u&&r&&br(t),u?Promise.resolve(e).then(()=>{c?n():h()},t=>h(!0,t)).catch(()=>{}):p?h(!0,new Error("Fullscreen request failed")):m()}catch(v){h(!0,v)}return{promise:f,cancel:()=>i.dispose()}}function xr(t,e){const r=P(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,u=!1,p=!1;function f(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch(t){}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),f()}),At(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=gr.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void f();if(r===s||M(t))return;s=r;const o=l,a=()=>M(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),At(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!M(t)&&t.emit("fullscreenError",r)}),{get:()=>!M(t)&&i(),set(n){if(M(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?u=!1:d&&(u=!0),null==a||a.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();p=!0,d=c;const s=wr(e,r,c,()=>{!M(t)&&c||f()},()=>!i());p=!1,l===o?a=s:s.cancel();const h=s.promise.catch(e=>{throw M(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return h.catch(()=>{}),h}}}const kr=new WeakSet;function $r(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Er(t){kr.delete(t),t.removeEventListener("webkitbeginfullscreen",Ar),t.removeEventListener("webkitpresentationmodechanged",Ar)}function Ar(t){var e;if(kr.has(this)&&$r(this,"webkitbeginfullscreen"===t.type)){Er(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function Cr(t){kr.add(t),t.addEventListener("webkitbeginfullscreen",Ar),t.addEventListener("webkitpresentationmodechanged",Ar)}function Sr(t){const{$video:e}=t.template,r=P(t).child();let n=!1,o=$r(e),i=o,a=!1,s=0;const l=()=>$r(e,n);function c(r){if(M(t)||(c=e,kr.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>M(t)||l()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{var t;s++,i=!1,a&&Cr(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),At(r,e,"webkitbeginfullscreen",()=>c(!0)),At(r,e,"webkitendfullscreen",()=>c(!1)),At(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!M(t)&&l(),set(r){if(M(t))return;const n=++s;if(i=Boolean(r),r){if(Er(e),t.state="fullscreen",M(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,Cr(e)),l()&&e.webkitExitFullscreen()}}}function Tr(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Lr({node:t,parent:e,next:r}){var n;if(!e)return void(null==(n=t.parentNode)||n.removeChild(t));const o=(null==r?void 0:r.parentNode)===e?r:null;t.parentNode===e&&t.nextSibling===o||e.insertBefore(t,o)}function Pr(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function Mr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function zr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),Mt(o,e,()=>e.click(),r),Mt(o,i,()=>(t.playing?c:l).click(),r);const d=t.i18n.get("Close");if(o.closed||M(t))return;e.setAttribute("aria-label",d);const u=t.i18n.get("Mini Player");if(o.closed||M(t))return;s.setAttribute("role","group"),s.setAttribute("aria-label",u),At(o,s,"keydown",t=>{const e=t;r()&&Pt(e)&&!e.defaultPrevented&&"Escape"===e.key&&(Lt(e),n())}),At(o,e,"click",n),At(o,l,"click",()=>{at(t.play())}),At(o,c,"click",()=>{t.pause()});const p=()=>{if(o.closed)return;const e=t.i18n.get(t.playing?"Pause":"Play");o.closed||M(t)||(i.setAttribute("aria-label",e),l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};p();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,p),o.add(()=>{t.off(r,p)});const f=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};At(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=Pr(i.left,i.top,Mr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:f,fresh:!0,focus:()=>e.focus({preventScroll:!0})}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function Or(t){const{$player:e,$video:r}=t.template,n=P(t).child();let o,i,a=0,c=!1,d=!1;const u=()=>!M(t)&&e.classList.contains("art-mini"),p=function(t){const e=t.template.$player;let r;return{entering(){var n;const o=e.ownerDocument,i=o.activeElement,a=i&&e.contains(i);(null==(n=t.template.$mini)?void 0:n.contains(i))||(r=a?ee(i):void 0);const s=a&&e.classList.contains("art-keyboard-focus");return e=>{!s||M(t)||o.activeElement!==i&&o.activeElement!==o.body||null==e||e()}},leaving(n){const o=e.ownerDocument,i=null==n?void 0:n.contains(o.activeElement);return()=>{var e;if(!i||M(t)||o.activeElement!==o.body&&!(null==n?void 0:n.contains(o.activeElement)))return;const a=r&&(null==(e=o.defaultView)?void 0:e.getComputedStyle(r).visibility);(null==r?void 0:r.isConnected)&&r.getClientRects().length&&"hidden"!==a&&"collapse"!==a&&"true"!==r.getAttribute("aria-disabled")&&!r.matches(":disabled")&&!r.closest("[inert]")?r.focus({preventScroll:!0}):Dt(t)}}}}(t);function f(){if(i){const e=i,r=a;i=void 0;try{Lr(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(M(t))return;const r=++a;d=!1;const n=p.leaving(t.template.$mini);f(),M(t)||r!==a||(null==o||o.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",n(),M(t)||r!==a||t.emit("mini",!1)))}function m(){if(M(t))return;const v=++a;if(c)return void(d=!0);const g=p.entering();if(t.state="mini",!M(t)&&v===a){null!=i||(i=Tr(r)),e.classList.add("art-mini");try{if(!o){c=!0;try{o=zr(t,n,u,h)}finally{c=!1}}if(d)return d=!1,void m();if(!o||M(t))return;if(v!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),M(t)||v!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:l(s({},Pr(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,Mr(o.element));if(M(t)||v!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),M(t)||v!==a)return;t.storage.set("left",i.left)}M(t)||v!==a||g(o.focus),M(t)||v!==a||t.emit("mini",!0)}catch(y){const r=d;throw d=!1,M(t)||v!==a&&!r||(f(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),y}}}return n.add(()=>{a++;try{f()}finally{null==o||o.cancelDrag(),e.classList.remove("art-mini")}}),{get:u,set(t){t?m():h()}}}const Rr=new WeakSet,Dr=t=>"picture-in-picture"===t.webkitPresentationMode;function Ir(t){Rr.delete(t),t.removeEventListener("webkitpresentationmodechanged",Nr),t.removeEventListener("enterpictureinpicture",Nr)}function Nr(){var t;if(Rr.has(this)&&Dr(this)){Ir(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function _r(t){Rr.add(t),t.addEventListener("webkitpresentationmodechanged",Nr),t.addEventListener("enterpictureinpicture",Nr)}function Wr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function Fr(t,e,r){return new Promise((n,o)=>{if(M(t)||e===t.url)return void n();const i=de(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const d=()=>!s&&i.active(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!d())return;const p=a.child();let f=!1,h=!1,m=!1;const v=we(t,r,d),g=()=>c(null,null,function*(){if(t.aspectRatio=o,d()){if(n)try{yield t.play()}catch(e){}d()&&(t.notice.show="",l())}}),y=()=>{var e,r;if(d()&&!h&&f)try{if(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)return;if(!d())return;if(m||(m=!0,t.playbackRate=s),!v.ready()||!d()||h)return;h=!0,p.dispose(),g().catch(u)}catch(n){u(n)}},b={"video:error":u,"video:loadedmetadata":()=>{if(d())try{v.restore()}catch(t){u(t)}},"video:canplay":()=>{f=!0,y()},"video:seeked":y,seek:v.manual},w=a.child(),x=[],k=Object.keys(b);for(const e of k)Wr(w,t,e,t=>{i.acceptingEvents&&x.push([e,t])},!1);if(pe(t,i,e),!d())return;if(t.notice.show="",!d())return;const $=()=>{if(w.dispose(),!e)return void l();const r={};for(const e of k)r[e]=Wr(p,t,e,b[e],"video:seeked"!==e);for(const[t,e]of x){if(!d()||p.closed)break;r[t](e)}x.length=0};i.assigned?$():i.onAssigned=$}catch(p){u(p)}})}function Vr(t){const{option:e,template:{$video:r}}=t;vt(t,"url",{get:()=>r.src,set(n){return c(this,null,function*(){if(M(t))return;const o=function(t){const e=ae.get(t);return ae.delete(t),e||de(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield St(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||st(n),s=e.customType[a];if(a&&s){if(!(yield St(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;Wr(l,t,"video:canplay",()=>{c=!d}),Wr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>fe(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||Wr(o.scope,t,"video:canplay",e)}}catch(i){fe(o,i)}finally{ue(o)}})}})}const Yr=[function(t){const{template:{$video:e}}=t;vt(t,"attr",{value(t,r){const n=e;if(void 0===r)return n[t];n[t]=r}})},function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;vt(t,"play",{value(){return c(this,null,function*(){const a=ce(t),s=yield i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})},function(t){const{notice:e}=t;vt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${ut(t.currentTime)} / ${ut(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;vt(t,"forward",{set(e){r.seek=t.currentTime+e}}),vt(t,"backward",{set(e){r.seek=t.currentTime-e}})},function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;vt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=ct(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),vt(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})},function(t){const{$video:e}=t.template;vt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){ye.set(t,be(t)+1)}(t),e.currentTime=ct(n,0,t.duration))}})},function(t){vt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})},function(t){const e=e=>Fr(t,e,0);vt(t,"switchQuality",{value:e=>Fr(t,e,t.currentTime)}),vt(t,"switchUrl",{value:e}),vt(t,"switch",{set:e})},function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;vt(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;vt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!M(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=lr({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(M(t))return;"width"===(null==r?void 0:r.axis)?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,M(t)||t.emit("aspectRatio",i)}}})},function(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=ce(t);return new Promise((a,s)=>{const l=r=>{try{!M(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}vt(t,"getDataURL",{value:()=>o(!1)}),vt(t,"getBlobUrl",{value:()=>o(!0)}),vt(t,"screenshot",{value:e=>c(null,null,function*(){const n=ce(t),o=yield t.getDataURL();if(!M(t)&&n()){const i=e||`artplayer_${ut(r.currentTime)}`;!M(t)&&n()&<(o,`${i}.png`),!M(t)&&n()&&t.emit("screenshot",o)}return o})})},function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(M(t))return;const i=function(t){const e=mr.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>vr(t,e.requestFullscreen,void 0),exit:()=>vr(r,e.exitFullscreen)}}(o);i?vt(t,"fullscreen",xr(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?vt(t,"fullscreen",Sr(t)):vt(t,"fullscreen",{get:()=>!1,set(){M(t)||(r.show=e.get("Fullscreen Not Supported"))}}),vt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),P(t).add(()=>{t.off("video:loadedmetadata",i)})},function(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(Lr(t.placement),r()))}return P(t).add(()=>{var t;n+=1;const i=r;if(r=void 0,i)try{o(i,()=>!0)}catch(a){try{e.parentNode!==i.placement.parent&&(null==(t=e.parentNode)||t.removeChild(e))}catch(s){throw new A([a,s])}throw a}}),i=>{if(M(t))return;const a=++n,s=()=>a===n&&!M(t),l=function(t){var e;const r=null==(e=t.ownerDocument)?void 0:e.activeElement,n=r&&t.contains(r);return()=>{n&&r.isConnected&&t.contains(r)&&r.ownerDocument.activeElement===r.ownerDocument.body&&r.focus({preventScroll:!0})}}(e);if(i){r||(r={placement:Tr(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(c){throw s()&&o(n,s)&&(r=void 0,l()),c}if(!s())return;if(l(),!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;if(l(),!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);vt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})},function(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?vt(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=P(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch(t){}}function u(e,r,n){e.then(()=>{!r||!M(t)&&a||d()},e=>{M(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),At(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!M(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),At(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!M(t)&&o()?e:null,set(n){if(M(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",M(t)||c!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?vt(t,"pip",function(t){const{$video:e}=t.template,r=P(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(M(t)||Rr.has(e))return;const s=Dr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),M(t)||i!==l||Dr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&_r(e),Dr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])At(r,e,l,()=>s());return{get:()=>!M(t)&&Dr(e),set(r){var n;if(M(t))return;const l=++i,c=a;if(r){if(!1===(null==(n=e.webkitSupportsPresentationMode)?void 0:n.call(e,"picture-in-picture")))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(Ir(e),t.state="pip",M(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,_r(e)),Dr(e)&&e.webkitSetPresentationMode("inline");M(t)||l!==i||c!==a||Dr(e)!==Boolean(r)||s(!0)}}}(t)):vt(t,"pip",{get:()=>!1,set(){M(t)||(r.show=e.get("PIP Not Supported"))}})},function(t){const{$video:e}=t.template,r=t;vt(t,"loaded",{get:()=>r.loadedTime/e.duration}),vt(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})},function(t){vt(t,"played",{get:()=>t.currentTime/t.duration})},function(t){const{$video:e}=t.template;vt(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})},function(t){const{$container:e,$player:r,$video:n}=t.template;vt(t,"autoSize",{value(){if(M(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!sr(o))return;const i=Y(e),a=lr(i,o.width/o.height);a&&!M(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})},function(t){const e=t;vt(t,"rect",{get:()=>Y(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}vt(t,"x",{get:()=>e.left+window.pageXOffset}),vt(t,"y",{get:()=>e.top+window.pageYOffset})},function(t){const{template:{$player:e},i18n:r,notice:n}=t;vt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){M(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,M(t)||t.emit("flip",o))}})},function(t){vt(t,"mini",Or(t))},function(t){const{template:{$poster:e}}=t;vt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){et(e,"backgroundImage",`url(${t})`)}})},function(t){const{$container:e,$video:r}=t.template;vt(t,"autoHeight",{value(){if(M(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!sr(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||M(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})},function(t){const{$player:e}=t.template;vt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})},function(t){vt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})},function(t){vt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})},function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];vt(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;n{if(!M(t))switch(e.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,M(t)||vt(t,"airplay",{value(){if(!M(t))if(i){const e=o.webkitShowPlaybackTargetPicker;if(M(t))return;Reflect.apply(e,o,[]),M(t)||t.emit("airplay")}else{const n=e.get("AirPlay Not Available");M(t)||(r.show=n)}}}))},function(t){vt(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:(null==i?void 0:i.html)||"",selector:e,onSelect(e,r,i){return c(this,null,function*(){const r=function(t){return t&&Ee.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!M(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!M(t)&&r()&&(n.show=i)}return e.html})}})}})},function(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,l=P(t).child(),c=!1;function d(){const e=l;l=P(t).child(),o=void 0,c=!1,a=void 0,e.dispose()}function u(){const i=a,c=l;if(!i||!o)return;const d=()=>{var e;return!M(t)&&!c.closed&&l===c&&a===i&&i.sourceActive()&&(null==(e=t.controls)?void 0:e.thumbnails)===i.element};if(!d())return;const u=r.clientWidth*i.percentage;if(!(u>0&&ud-f/2?d-f+"px":u-f/2+"px"}}(e.thumbnails,{imageWidth:o.naturalWidth,videoWidth:n.videoWidth,videoHeight:n.videoHeight,progressWidth:r.clientWidth,position:u}));for(const[t,e]of Object.entries(p)){if(!d())return;et(i.element,t,e)}}_e(t)("setBar",(r,n,s)=>{var p;const f=null==(p=t.controls)?void 0:p.thumbnails,{url:h,scale:m}=e.thumbnails;if(!M(t)&&f&&h&&("hover"===r||"played"===r&&s&&k)){if(i!==f){const t=D(f);if(t.closed)return;i=f,t.add(()=>{i===f&&(i=void 0,d())})}if(a={percentage:n,element:f,sourceActive:ce(t)},o)u();else if(!c){const t=l;c=!0,function(t,e,r){return nt(t,e,r)}(h,m,t).then(e=>{l!==t||t.closed||(c=!1,o=e,u())}).catch(e=>{l!==t||t.closed||(c=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),vt(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{M(t)||!e.url||t.option.isLive||M(t)||(t.option.thumbnails=e,d())}})},function(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{M(t)||t.emit(`video:${e.type}`,e)})}(t);const e=ur(t);!function(t,e){cr(t,"video:canplay",()=>{e.reset(),dr(t,[["loading",!1]])}),cr(t,"video:canplay",()=>{dr(t,[["loading",!1],["controls",!0],["mask",!0]]),M(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;cr(t,"video:ended",()=>{if(e.loop){const e=ce(t);if(t.seek=0,M(t)||!e())return;at(t.play()),e()&&dr(t,[["controls",!1],["mask",!1]],e)}else dr(t,[["controls",!0],["mask",!0]])})}(t),cr(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;cr(t,"video:loadedmetadata",()=>{t.emit("resize"),k&&dr(t,[["loading",!1],["controls",!0],["mask",!0]])}),cr(t,"video:loadstart",()=>{e.loadStart(),dr(t,[["loading",!0],["mask",!1],["controls",!0]])}),cr(t,"video:pause",()=>{dr(t,[["controls",!0],["mask",!0]])}),cr(t,"video:play",()=>{dr(t,[["mask",!1]]),M(t)||et(r,"display","none")}),cr(t,"video:playing",()=>dr(t,[["mask",!1]])),cr(t,"video:progress",()=>{t.playing&&dr(t,[["loading",!1]])}),cr(t,"video:seeked",()=>dr(t,[["loading",!1],["mask",!0]])),cr(t,"video:seeking",()=>dr(t,[["loading",!0],["mask",!1]])),cr(t,"video:timeupdate",()=>dr(t,[["mask",!1]])),cr(t,"video:waiting",()=>dr(t,[["loading",!0],["mask",!1]]))}(t,e)},function(t){if(M(t))return;const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const s in e.moreVideoAttr){if(M(t))return;const r=e.moreVideoAttr[s];if(M(t))return;t.attr(s,r)}if(M(t))return;if(e.muted){const r=e.muted;if(M(t))return;t.muted=r}if(M(t))return;if(e.volume){const r=ct(e.volume,0,1);if(M(t))return;n.volume=r}if(M(t))return;const i=r.get("volume");if(M(t))return;if("number"===typeof i&&(n.volume=ct(i,0,1)),M(t))return;if(e.poster){const r=`url(${e.poster})`;if(M(t))return;et(o,"backgroundImage",r)}if(M(t))return;if(e.autoplay){const r=e.autoplay;if(M(t))return;n.autoplay=r}if(M(t))return;if(e.playsInline){if(M(t))return;if(n.playsInline=!0,M(t))return;n["webkit-playsinline"]=!0}if(M(t))return;if(e.theme){const r=e.cssVar,n=e.theme;if(M(t))return;r["--art-theme"]=n}for(const s in e.cssVar){if(M(t))return;const r=e.cssVar[s];if(M(t))return;t.cssVar(s,r)}if(M(t))return;const a=e.url;M(t)||(t.url=a)}];class Br{constructor(t){if(!M(t)){Vr(t);for(const e of Yr){if(M(t))return;e(t)}}}}const Hr=new WeakMap,jr="art-auto-orientation-fullscreen";function qr(t){if(Hr.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const Ur="art-auto-orientation",Xr=["width","height","transform-origin","transform"];function Gr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return sr(t)&&sr(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=P(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(Ur);r.classList.remove(Ur),n&&(t.isRotate=!1,M(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=B();if(M(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=Xr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(Ur),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;M(t)||(r?o?s(!1):e()&&(i(),i=Ct(n,()=>{o||s(!0)},Number(null!=(l=t.constructor.AUTO_ORIENTATION_TIME)?l:0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(jr),t&&(t.cancelled=!0,qr(t),t.settled&&Hr.get(t.orientation)===t&&Hr.delete(t.orientation))}return P(t).add(o),i=>{var a,s;if(M(t))return;if(!i)return void o();if(n&&!n.cancelled&&Hr.get(n.orientation)===n)return;const l=null==(s=null==(a=r.ownerDocument.defaultView)?void 0:a.screen)?void 0:s.orientation;if("function"!==typeof(null==l?void 0:l.lock)||"function"!==typeof l.unlock||!e())return;const c={orientation:l,cancelled:!1,settled:!1};n=c,Hr.set(l,c);const d=()=>!M(t)&&!c.cancelled&&n===c&&Hr.get(l)===c,u=e=>{c.settled=!0;const o=d();Hr.get(l)===c&&Hr.delete(l),n===c&&(n=void 0),o&&(r.classList.remove(jr),t.notice.show=e)};try{const t=l.lock(l.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{c.settled=!0,d()?r.classList.add(jr):(qr(c),Hr.get(l)===c&&Hr.delete(l))}).catch(u)}catch(p){u(p)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),P(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Kr(t){return t.get("times")||{}}function Zr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||M(t))return()=>{};const s=Ot(".art-auto-playback-last",a),l=Ot(".art-auto-playback-jump",a),c=Ot(".art-auto-playback-close",a);zt(c,r.close);const d=D(a);let u,p=0;const f=()=>{const r=++p;if(null==u||u.dispose(),d.closed||M(t)||p!==r)return;const f=d.child();u=f;const h=()=>u===f&&!f.closed&&!M(t);f.add(()=>{u===f&&(u=void 0,et(a,"display","none"))});const m=le(t).add(()=>{f.dispose()});f.add(()=>{m()});const v=Kr(n)[t.option.id||t.option.url];if(!h())return;if(et(a,"display","none"),!h()||!v||!(v>=o.AUTO_PLAYBACK_MIN))return;if(!h())return;if(et(a,"display","flex"),!h())return;const g=`${e.get("Last Seen")} ${ut(v)}`;if(!h())return;if(s.textContent=g,!h())return;const y=e.get("Jump Play");if(!h())return;if(l.textContent=y,!h())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{h()&&r()});f.add(()=>{t.events.remove(n)})};if(b(c,()=>{et(a,"display","none")}),!h())return;if(b(l,()=>{t.seek=v,h()&&(at(t.play()),h()&&(et(i,"display","none"),h()&&et(a,"display","none")))}),!h())return;let w=()=>{},x=!1;const k=()=>{!x&&h()&&(x=!0,w(),Ct(f,()=>{h()&&et(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",k),w=f.add(()=>{t.off("video:timeupdate",k)}),x&&w()};return()=>{N(t,a,"ready",f),N(t,a,"restart",f)}}(t);return function(t){const{storage:e,constructor:r}=t;_e(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Kr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;M(t)||(o.length>i&&delete n[o[0]],n[a]=s,M(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Kr(e)},clear:()=>e.del("times"),delete(t){const r=Kr(e);return delete r[t],e.set("times",r),r}}}function Jr(t){let e,r=0;return{start:n=>{const o=++r;if(null==e||e.scope.dispose(),o!==r||M(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:le(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{(null==e?void 0:e.active)||q(t.template.$player,"art-fast-forward")}}),Ct(i.scope,()=>{if(e!==i||M(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||M(t))return;t.playbackRate=r,e!==i||i.scope.closed||M(t)||j(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,null==e||e.scope.dispose()}}}function Qr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Jr(t),i=_e(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return U(r,"art-fast-forward")}}}function tn(t,e,r,n){let o;const i=()=>!r.closed&&!M(t),a=t.i18n.get("Lock");if(!i())return()=>{};e.setAttribute("aria-label",a),Mt(r,e),At(r,e,"keydown",t=>{const r=t;i()&&n()&&Pt(r)&&!r.defaultPrevented&&"Escape"===r.key&&(Lt(r),e.click())});const s=n=>{if(i())if(e.setAttribute("aria-pressed",String(n)),n&&!o){const{$player:n,$bottom:a}=t.template,s=a.contains(a.ownerDocument.activeElement)&&n.classList.contains("art-keyboard-focus");o=r.child(),function(t,e){const r=new Map,n=e.hasAttribute("inert"),o=e.getAttribute("aria-hidden"),i=(t,e)=>{"-1"===t.getAttribute("tabindex")&&(null===e?t.removeAttribute("tabindex"):t.setAttribute("tabindex",e))};if(t.add(()=>{for(const[t,e]of r)i(t,e);r.clear(),n||""!==e.getAttribute("inert")||e.removeAttribute("inert"),"true"===e.getAttribute("aria-hidden")&&(null===o?e.removeAttribute("aria-hidden"):e.setAttribute("aria-hidden",o))}),t.closed)return;n||e.setAttribute("inert",""),e.setAttribute("aria-hidden","true");const a=()=>{if(!t.closed){for(const[t,n]of r)e.contains(t)||(i(t,n),r.delete(t));for(const t of e.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]"))r.has(t)||(r.set(t,t.getAttribute("tabindex")),t.setAttribute("tabindex","-1"))}};if(a(),"undefined"!==typeof MutationObserver){const r=new MutationObserver(a);r.observe(e,{childList:!0,subtree:!0}),t.add(()=>{r.disconnect()})}}(o,a),i()&&s&&e.focus({preventScroll:!0})}else if(!n&&o){const t=o;o=void 0,t.dispose()}};return s(n()),s}function en(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return U(n,"art-lock")}function i(){M(t)||(j(n,"art-lock"),M(t)||(t.isLock=!0,M(t)||t.emit("lock",!0)))}function a(){M(t)||(q(n,"art-lock"),M(t)||(t.isLock=!1,M(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=D(e);if(n.closed||M(t))return;const i=zt(e,r.lock);if(n.closed||M(t))return;const a=zt(e,r.unlock);if(n.closed||M(t))return;const s=tn(t,e,n,o);n.closed||M(t)||(o()?(et(i,"display","inline-flex"),n.closed||M(t)||et(a,"display","none")):et(i,"display","none"),N(t,e,"lock",e=>{M(t)||(et(i,"display",e?"inline-flex":"none"),n.closed||M(t)||et(a,"display",e?"none":"inline-flex"),n.closed||M(t)||s(e))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function rn(t){return _e(t)("control",e=>{e?q(t.template.$player,"art-mini-progress-bar"):j(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class nn{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){M(t.art)||!e.miniProgressBar||e.isLive||t.add(rn),!M(t.art)&&e.lock&&k&&t.add(en),M(t.art)||!e.autoPlayback||e.isLive||t.add(Zr),!M(t.art)&&e.autoOrientation&&k&&t.add(Gr),!M(t.art)&&e.fastForward&&k&&!e.isLive&&t.add(Qr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!M(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(M(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(M(t.art))return t;let o=n;const i=yt(t,o);if(M(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return M(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),M(t.art)||vt(t,o,{value:r})),t}(this,t,e)}}const on=new WeakMap;function an(t){return!t.closed&&!on.get(t)}function sn(t){on.set(t,(on.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(on.get(t)||1)-1;r?on.set(t,r):on.delete(t)}}const ln=new WeakMap,cn=new WeakMap,dn=["$parent","$parents","$option","$events","$formatted"];function un(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=ln.get(o);if(!t||!t.owner.active||(null==(e=t.owner.scope)?void 0:e.closed)||!t.option.includes(o))return!1;if(!t.parent)return t.owner.root===t.option;if((null==(r=ln.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function pn(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function fn(t){const e=ln.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function hn(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>xn(t,o)])try{e()}catch(d){d instanceof A?l.push(...d.errors):l.push(d)}if(r.closed||M(t)||(o.push(...i.splice(0)),wn.set(r,o),yn.set(e,r),bn.set(e,n)),a(),l.length)throw new A(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function Cn(t,e,r,n,o,i){const a=i||$n(e);if(!an(a)||M(t))return;const s=t.proxy(r,n,e=>{if(an(a)&&!M(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!an(a)||M(t)?t.events.remove(s):(fn(e).events.push(s),i&&i!==yn.get(e)&&i.add(()=>{const r=fn(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Sn(t,e,r,n){const o=$n(e);if(!an(o)||M(t))return;const i=(...e)=>{if(an(o)&&!M(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Tn(t){var e;const r=null==(e=t.ownerDocument.defaultView)?void 0:e.getComputedStyle(t).visibility;return t.isConnected&&!t.matches(":disabled")&&!t.closest("[inert]")&&"true"!==t.getAttribute("aria-disabled")&&t.getClientRects().length>0&&"hidden"!==r&&"collapse"!==r}function Ln(t){return Array.from(t.querySelectorAll('[tabindex="0"],button,input,select,textarea,a[href],[contenteditable]')).filter(t=>"-1"!==t.getAttribute("tabindex")&&Tn(t))}function Pn(t,e,r=!1){if(!t.show||M(t.art)||!t.active)return;const n=t.cache.get(t.active);if(!n||!an(vn(n)))return;const o=Ln(n),i=n.querySelector(".art-setting-item.art-current"),a=o.find(t=>e===t||(null==e?void 0:e.contains(t)))||(r?o[o.length-1]:o.find(t=>null==i?void 0:i.contains(t))||o.find(t=>!t.classList.contains("art-setting-item-back"))||o[0]);null==a||a.focus({preventScroll:!0}),M(t.art)||null==a||a.scrollIntoView({block:"nearest",inline:"nearest"})}function Mn(t){const e=t.$parent.ownerDocument,r=e.activeElement,n=t.$parent.contains(r);return o=>{n&&!M(t.art)&&(e.activeElement===e.body||e.activeElement===r&&!(null==r?void 0:r.getClientRects().length))&&Pn(t,o)}}function zn(t){const{art:e}=t,r=P(e).child();if(r.closed)return;const n=()=>t.$parent.ownerDocument;let o=!1;const i=()=>{t.show=!1,r.closed||M(e)||t.render()},a=i=>{r.closed||M(e)||(i?n().activeElement===e.controls.setting&&e.template.$player.classList.contains("art-keyboard-focus")&&Pn(t,void 0,o):t.$parent.contains(n().activeElement)&&function(t){const{art:e,$parent:r}=t,n=e.template.$player,o=r.ownerDocument,i=e.controls.setting;!M(e)&&r.contains(o.activeElement)&&(i&&n.contains(i)&&Tn(i)&&i.focus({preventScroll:!0}),(o.activeElement===o.body||r.contains(o.activeElement))&&Dt(e))}(t))};e.on("setting",a),r.add(()=>{e.off("setting",a)}),At(r,e.template.$player,"keydown",r=>{var n,a;const s=r;if(!Pt(s)||s.defaultPrevented||M(e))return;const l=s.target;if(l===e.controls.setting){if("ArrowDown"===s.key||"ArrowUp"===s.key)if(Lt(s),t.show)Pn(t,void 0,"ArrowUp"===s.key);else{o="ArrowUp"===s.key;try{t.show=!0}finally{o=!1}}else"Escape"===s.key&&t.show&&(Lt(s),i());return}if(!t.show||!t.$parent.contains(l))return;if("Escape"===s.key)return Lt(s),void i();const c=l.closest(".art-setting-item");if(!c||l!==c&&!l.matches('button,a[href],[role="button"]'))return;const d=t.active&&t.cache.get(t.active);if(!d)return;const u=null==(n=t.active)?void 0:n.find(t=>t.$item===c);if(!an(vn(d))||u&&!an($n(u)))return void(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End"].includes(s.key)&&Lt(s));const p=Ln(d),f=p.indexOf(l);if(f<0)return;let h;switch(s.key){case"ArrowDown":h=Math.min(f+1,p.length-1);break;case"ArrowUp":h=Math.max(f-1,0);break;case"Home":h=0;break;case"End":h=p.length-1;break;case"ArrowLeft":{const t=d.querySelector(".art-setting-item-back");return Lt(s),void(null==t||t.click())}case"ArrowRight":return Lt(s),void((null==(a=null==u?void 0:u.selector)?void 0:a.length)&&l.click());default:return}Lt(s),void 0!==h&&Pn(t,p[h])});let s=!1;At(r,t.$parent,"focusout",o=>{const a=o.relatedTarget;a&&(t.$parent.contains(a)||a===e.controls.setting)||s||(s=!0,Ct(r,()=>{s=!1,r.closed||M(e)||!t.show||t.$parent.contains(n().activeElement)||n().activeElement===e.controls.setting||i()},0))})}function On(t){var e,r;const{art:n,active:o}=t,{controls:i,constructor:{SETTING_WIDTH:a,SETTING_ITEM_HEIGHT:s},template:{$player:l,$setting:c,$bottom:d}}=n;if(!i.setting||!t.show||!o)return;const u=l.getBoundingClientRect(),p=i.setting.getBoundingClientRect(),f=u.width/l.offsetWidth||1,h=(p.left-u.left+p.width/2)/f-l.clientLeft,m=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:l.clientWidth,containerHeight:l.clientHeight,requestedWidth:(null==(r=null==(e=o[0])?void 0:e.$parent)?void 0:r.width)||a,rows:o.length+(o===t.option?0:1),rowHeight:s,controlCenter:h,bottom:Number.parseFloat(getComputedStyle(c).bottom)||0,padding:Number.parseFloat(getComputedStyle(d).paddingLeft)||0});c.style.height=`${m.height}px`,c.style.width=`${m.width}px`,n.isRotate||k||(h+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const Rn=new WeakMap;function Dn(t){Rn.delete(t)}const In=new WeakMap;function Nn(t,e){e?In.set(t,e):In.delete(t)}function _n(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=In.get(t),i=null==o?void 0:o();for(const a of["html","icon","tooltip"]){const t=null==(e=r.get(a))?void 0:e.value;t instanceof Node&&n.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{var e,a;for(const n of Reflect.ownKeys(t))!r.has(n)&&(null==(e=Object.getOwnPropertyDescriptor(t,n))?void 0:e.configurable)&&Reflect.deleteProperty(t,n);for(const[n,o]of r)Object.defineProperty(t,n,o);null==i||i(),Nn(t,o);for(const{node:t,parent:r,next:o}of n)r?r.insertBefore(t,(null==o?void 0:o.parentNode)===r?o:null):null==(a=t.parentNode)||a.removeChild(t)}}function Wn(t){var e,r;const n=null==(e=t.$item)?void 0:e.querySelector(".art-setting-range");n&&n.setAttribute("aria-label",(null==(r=t.$html)?void 0:r.textContent)||"")}const Fn=new WeakMap;function Vn(t,e,r,n,o,i,a,s){return c(this,null,function*(){try{const l=$n(e),c=$n(i),d=(Fn.get(i)||0)+1;Fn.set(i,d);const u=()=>an(l)&&an(c)&&!M(t.art)&&Fn.get(i)===d;if(null==s||s(),!u())return;const p=yield o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}})}function Yn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const Bn=new WeakMap;function Hn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof A?e.push(...r.errors):e.push(r)}if(e.length)throw new A(e)}function jn(t){var e;null==(e=Bn.get(t))||e()}function qn(t,e){const r=t.find(e.name);if(M(t.art))return r||e;if(!r)return t.add(e);const n=Mn(t);Dn(r),jn(r);const o=_n(r),i=r.$item,a=null==i?void 0:i.parentNode,s=null==i?void 0:i.nextSibling,l=i?Yn(i):void 0,c=t.active,d=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),u=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=An(t.art,e);r&&i.push(r)}for(const t of n)a.push(sn(vn(t)))}catch(l){try{Hn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,Hn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,Hn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>gn(t)),...a]))}}}(t,r);let p=!0,f=!1;const h=()=>{if(!p)return;p=!1;for(const t of u.items)Bn.get(t)===h&&Bn.delete(t);if(M(t.art))return void u.dispose();const e=r.$item;try{Hn([u.resume,()=>{e&&e!==i&&e.remove()},o,()=>null==l?void 0:l(),()=>{a&&i&&a.insertBefore(i,(null==s?void 0:s.parentNode)===a?s:null)},()=>t.format(),()=>{if(f){t.active=c,c&&t.cache.has(c)&&K(t.cache.get(c),"art-current");for(const[e,r,n]of d)t.$parent.style.setProperty(e,r,n)}}]),n(i)}catch(m){console.warn("ArtPlayer setting restore failed:",m)}},m=()=>p&&!M(t.art)&&Bn.get(r)===h;for(const y of u.items)Bn.set(y,h);const v=P(t.art).add(()=>{p=!1;for(const t of u.items)Bn.get(t)===h&&Bn.delete(t);u.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!(null==o?void 0:o.enumerable)||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,m),!m())return r;if(t.format(),!m())return r;if(t.createItem(r,!0),!m())return r;if(f=!0,t.render(),!m())return r;p=!1;for(const t of u.items)Bn.get(t)===h&&Bn.delete(t);return u.dispose(),n(r.$item),r}catch(g){throw m()&&h(),g}finally{v()}}const Un=new WeakMap;function Xn(t,e,r){vt(t,`$${e}`,{configurable:!0,get:()=>r}),vt(t,e,{configurable:!0,get:()=>r.innerHTML,set(n){r.innerHTML="",X(r,n),"html"===e&&Wn(t)}})}function Gn(t,e,r=!1){var n,o;const i=function(t){const e=Bn.get(t);return()=>!e||Bn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";yt(e,"switch")&&(l="switch"),yt(e,"range")&&(l="range"),yt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=P(t)){const n=yn.get(e);(!n||an(n)||n.closed)&&En(t,e);const o=r.child();return yn.set(e,o),bn.set(e,r),wn.set(o,fn(e).events),o.add(()=>{xn(t,wn.get(o))}),o}(t.art,e,vn(a)),p=()=>an(u)&&!M(t.art)&&i();if(!p())return;const f=document.createElement("div");try{if(Nn(e),j(f,"art-setting-item"),et(f,"height",`${d.SETTING_ITEM_HEIGHT}px`),f.dataset.name=e.name||"",f.dataset.value=String(e.value||""),!p())return;const i=zt(f,'
'),h=zt(f,'
'),m=document.createElement("div");switch(j(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;X(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;X(m,t)}else X(m,c.check)}if(X(i,m),!p())return;Xn(e,"icon",m);const v=document.createElement("div");j(v,"art-setting-item-left-text");const g=e.html||"";if(!p())return;X(v,g),X(i,v),Xn(e,"html",v);const y=document.createElement("div");j(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(X(y,b),X(h,y),Xn(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");j(t,"art-setting-item-right-icon");const r=zt(t,c.switchOn),n=zt(t,c.switchOff),o=e.switch;if(!p())return;et(o?n:r,"display","none"),X(h,t),vt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;Nn(e,()=>{const t=i;return()=>{i=t}}),vt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,f.setAttribute("aria-checked",String(Boolean(t))),t?(et(n,"display","none"),et(r,"display",null)):(et(n,"display",null),et(r,"display","none"))}});break}case"range":{const t=document.createElement("div");j(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",X(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!p())return;Reflect.set(r,i,String(t))}j(r,"art-setting-range"),X(h,t),vt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;Nn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),vt(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(null==(o=e.selector)?void 0:o.length){const t=document.createElement("div");j(t,"art-setting-item-right-icon"),X(t,c.arrowRight),X(h,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=$n(e),a=(t,r,n)=>Cn(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>Vn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>Vn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{var o,i;if(null==(o=e.selector)?void 0:o.length)t.render(e.selector);else{if(null==(i=e.$parent)?void 0:i.onSelect)return Vn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&j(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>Vn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,f,l),!p())return;vt(e,"$item",{configurable:!0,get:()=>f}),function(t,e,r,n,o){var i;"range"!==n?r.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")||("switch"===n?(r.setAttribute("role","switch"),r.setAttribute("aria-checked",String(Boolean(e.switch))),r.setAttribute("aria-disabled",String(!e.onSwitch))):"selector"!==n||(null==(i=e.selector)?void 0:i.length)||r.setAttribute("aria-current",String(Boolean(e.default))),Mt(o,r,()=>r.click(),()=>an(o)&&!M(t.art))):Wn(e)}(t,e,f,l,u),r&&(null==s?void 0:s.parentNode)?s.replaceWith(f):X(a,f),e.mounted&&p()&&Ct(u,()=>{var r;if(!M(t.art))try{const n=null==(r=e.mounted)?void 0:r.call(t.art,f,e);Promise.resolve(n).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(n){console.warn("ArtPlayer setting mounted failed:",n)}},0)}catch(h){try{u.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw f.remove(),h}}function Kn(t,e=t.option){var r,n,o,i,a,s;if(M(t.art))return;const l=Mn(t),c=t.cache.get(e);if(c&&!an(vn(c)))return;const d=(Un.get(t)||0)+1;Un.set(t,d);const u=()=>Un.get(t)===d&&!M(t.art),p=t.active,f=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),h=()=>{t.active=p,p&&t.cache.has(p)&&K(t.cache.get(p),"art-current");for(const[e,r,n]of f)t.$parent.style.setProperty(e,r,n)};if(t.active=e,c)try{K(c,"art-current"),t.resize()}catch(m){throw u()&&t.cache.get(e)===c&&!vn(c).closed&&h(),m}else{const a=document.createElement("div");t.cache.set(e,a);const s=function(t,e,r){const n=P(t.art).child();return mn.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,a),l=()=>!s.closed&&!M(t.art)&&t.cache.get(e)===a,c=[];try{if(!l())return;j(a,"art-setting-panel"),a.setAttribute("role","group"),a.setAttribute("aria-label",(null==(o=null==(n=null==(r=e[0])?void 0:r.$parent)?void 0:n.$html)?void 0:o.textContent)||t.art.i18n.get("Settings")),X(t.$parent,a),K(a,"art-current"),(null==(i=e[0])?void 0:i.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=cn.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=P(e).child(),n=(t,n)=>{if(r.closed||M(e))return;const o=(...t)=>{if(!r.closed&&!M(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=F(r,e.controls.setting),o=F(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||M(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this)),zn(this)}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),Sn(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),Sn(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(dt(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),Sn(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{Sn(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){hn(e,t)}check(t){!function(t,e){(null==e?void 0:e.$parent)&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.$item&&t.$item.setAttribute("aria-current",String(t.default)),t.default&&t.$item&&K(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=cn.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;ofn(t).parent},$parents:{get:()=>fn(t).parents},$option:{get:()=>fn(t).option},$events:{get:()=>fn(t).events},$formatted:{get:()=>!0}}),ln.set(t,{parent:r,parents:n,option:o,events:(null==a?void 0:a.events)||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return hn(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){On(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&gn(n)}catch(i){r.push(i)}}try{En(t.art,e)}catch(i){i instanceof A?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new A(r)}(this,t)}remove(t){const e=Mn(this),r=this.find(t);it(r,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Dn(t),jn(t)},[r]);const n=r.$option.indexOf(r);r.$option.splice(n,1);const o=r.$item,i=[];for(const s of[()=>this.inactivate(r),()=>null==o?void 0:o.remove(),()=>this.render()])try{s()}catch(a){a instanceof A?i.push(...a.errors):i.push(a)}if(i.length)throw new A(i);e()}update(t){return qn(this,t)}add(t,e=this.option){var r;if(M(this.art))return t;let n=!1;this.traverse(e=>{n||(n=e===t)});const o=e.length,i=n?void 0:function(t){const e={};Rn.set(t,e);const r=()=>Rn.get(t)===e;return{current:r,finish(){r()&&Rn.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(M(this.art)||i&&!i.current())throw s;if(e[o]===t&&e.splice(o,1),!n&&a){try{this.inactivate(t)}catch(l){console.warn("ArtPlayer setting cleanup failed:",l)}null==(r=t.$item)||r.remove()}throw s}finally{null==i||i.finish()}return t}createHeader(t){!function(t,e){var r;if(!t.cache.has(e.$option))return;const n=t.cache.get(e.$option),{icons:{arrowLeft:o},constructor:{SETTING_ITEM_HEIGHT:i}}=t.art,a=document.createElement("div");et(a,"height",`${i}px`),j(a,"art-setting-item"),j(a,"art-setting-item-back");const s=zt(a,'
'),l=document.createElement("div");j(l,"art-setting-item-left-icon"),X(l,o),X(s,l),X(s,e.$parent.html),Cn(t.art,e.$parent,a,"click",()=>t.render(e.$parents),vn(n));const c=vn(n);a.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")||Mt(c,a,()=>a.click(),()=>an(c)&&!M(t.art)),a.setAttribute("aria-label",`${t.art.i18n.get("Back")}: ${(null==(r=a.textContent)?void 0:r.trim())||""}`),X(n,a)}(this,t)}createItem(t,e=!1){Gn(this,t,e)}render(t=this.option){Kn(this,t)}}class Qn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch(e){return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch(r){this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch(e){delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch(t){this.settings={}}}}const to='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:opacity var(--art-transition-duration) ease,transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel,.art-control-volume:focus-within .art-volume-panel{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:focus-within .art-mini-close,.art-mini-popup:hover .art-mini-state,.art-mini-popup:focus-within .art-mini-state{opacity:1}.art-mini-popup [role=button]:focus-visible{outline:2px solid #fff;outline-offset:-2px}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-layer-lock{display:flex}.art-video-player.art-lock:not(.art-control-show) .art-layer-lock{opacity:0;pointer-events:none}.art-video-player.art-lock:not(.art-control-show) .art-layer-lock:focus-within{opacity:1;pointer-events:auto}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:opacity var(--art-transition-duration) ease,transform var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover:not(.art-selector-dismissed) .art-selector-list,.art-control-selector.art-selector-open .art-selector-list{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}.art-video-player [tabindex]:focus-visible,.art-video-player input:focus-visible,.art-video-player button:focus-visible,.art-video-player a:focus-visible{outline:2px solid currentColor;outline-offset:-2px}.art-video-player.art-keyboard-focus :focus{outline:2px solid currentColor;outline-offset:-2px}.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom{opacity:1}.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-controls,.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-progress{transform:translateY(0)}';class eo{constructor(t){var e;this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=null==(e=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope))?void 0:e.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}run(t){return c(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const ro=new WeakMap;function no(t){return ro.get(t)}function oo(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const io=Kt;class ao extends io{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=P(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return ro.set(t,n),r.add(()=>{oo(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){var t,e;return null==(e=null==(t=this.art.template.$video)?void 0:t.textTracks)?void 0:e[0]}get activeCues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.activeCues)||[])}get cues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.cues)||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?rt(r,t):et(r,t,e)}update(){!function(t){const e=no(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?mt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return c(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=l(s(s({},o.subtitle),e),{url:t}),a=no(this),c=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===c&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=no(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(c)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const f=n.track;n.track=u,t.destroyEvent=c,s.onload=null,s.onerror=null,p=!0;try{null==f||f.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&oo(n)}}catch(f){if(p)throw f;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw f;throw a.$track=s,l&&l.insertBefore(s,(null==c?void 0:c.parentNode)===l?c:null),f}}(this,t,e)}init(t){return c(this,null,function*(){const e=no(this),r=function(t){const e=t.request,r=new eo(t.scope);return t.request=r,t.revision+=1,null==e||e.cancel(),r}(e),{notice:n,template:{$subtitle:o}}=this.art;return r.run(()=>c(this,null,function*(){if(!this.textTrack)return null;if(h(t,Xt.subtitle),!t.url)return;let i;this.option=t,this.style(t.style);try{if(!r.active)return;const n=yield fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const a=yield n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||st(e.url)){case"srt":return{vtt:e.onVttLoad(xt(r))};case"ass":return{vtt:e.onVttLoad($t(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=kt(s.vtt);if(!r.active)return;o.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return i&&(e.ownedURL=i,i=void 0),l}catch(a){if(!r.active)return;throw o.innerHTML="",n.show=a,a}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}}))})}}const so=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${m}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class lo{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=H(e.container),it(this.$container,`No container element found by ${e.container}`)),it(V(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();it("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),it(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=T.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=L(t);o.rollback=r,T.set(e,t),o.releaseContainer=()=>{T.get(e)===t&&T.delete(e)}}(t,this.$container,Yn(this.$container)),function(t,e,r){const n=L(t),o=n.mountingTemplate;n.mountingTemplate=e;try{r()}finally{n.mountingTemplate=o}}(t,this,()=>{this.$container.dataset.artId=String(t.id),this.init()})}static get html(){return so}query(t){return H(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=lo.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);if(M(this.art))return;!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),Z(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&j(this.$player,"art-backdrop"),k&&j(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":j(this.$player,"art-destroy")}}const co=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class uo{on(t,e,r){const n=this.e||(this.e={});let o=co(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(co(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=co(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new lo(this),P(this).closed)return;if(this.events=new Fe(this),P(this).closed)return;if(this.storage=new Qn,P(this).closed)return;if(this.icons=new Ge(this),P(this).closed)return;if(this.i18n=new Ue(this),P(this).closed)return;if(this.notice=new ir(this),P(this).closed)return;if(this.player=new Br(this),P(this).closed)return;if(this.layers=new tr(this),P(this).closed)return;if(this.controls=new Pe(this),P(this).closed)return;if(this.contextmenu=new oe(this),P(this).closed)return;if(this.subtitle=new ao(this),P(this).closed)return;if(this.info=new Qe(this),P(this).closed)return;if(this.loading=new er(this),P(this).closed)return;if(this.hotkey=new je(this),P(this).closed)return;if(this.mask=new rr(this),P(this).closed)return;if(this.setting=new Jn(this),P(this).closed)return;if(this.plugins=new nn(this),P(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),ho.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${ho.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=L(t);return e.rollback=void 0,!e.scope.closed})(this)&&fo.push(this)}catch(r){try{z(this,fo,!0,ho.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return fo}static get version(){return m}static get config(){return E}static get utils(){return Et}static get scheme(){return Xt}static get Emitter(){return uo}static get validator(){return h}static get kindOf(){return h.kindOf}static get html(){return lo.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:b?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:null==navigator?void 0:navigator.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){z(this,fo,t,ho.REMOVE_SRC_WHEN_DESTROY)}}var mo,vo;return ho.STYLE=to,ho.DEBUG=!1,ho.CONTEXTMENU=!0,ho.NOTICE_TIME=2e3,ho.SETTING_WIDTH=250,ho.SETTING_ITEM_WIDTH=200,ho.SETTING_ITEM_HEIGHT=35,ho.RESIZE_TIME=200,ho.SCROLL_TIME=200,ho.SCROLL_GAP=50,ho.AUTO_PLAYBACK_MAX=10,ho.AUTO_PLAYBACK_MIN=5,ho.AUTO_PLAYBACK_TIMEOUT=3e3,ho.RECONNECT_TIME_MAX=5,ho.RECONNECT_SLEEP_TIME=1e3,ho.CONTROL_HIDE_TIME=3e3,ho.DBCLICK_TIME=300,ho.DBCLICK_FULLSCREEN=!0,ho.MOBILE_DBCLICK_PLAY=!0,ho.MOBILE_CLICK_PLAY=!1,ho.AUTO_ORIENTATION_TIME=200,ho.INFO_LOOP_TIME=1e3,ho.FAST_FORWARD_VALUE=3,ho.FAST_FORWARD_TIME=1e3,ho.TOUCH_MOVE_RATIO=.5,ho.VOLUME_STEP=.1,ho.SEEK_STEP=5,ho.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],ho.ASPECT_RATIO=["default","4:3","16:9"],ho.FLIP=["normal","horizontal","vertical"],ho.FULLSCREEN_WEB_IN_BODY=!0,ho.LOG_VERSION=!0,ho.USE_RAF=!1,ho.REMOVE_SRC_WHEN_DESTROY=!0,mo=ho,vo=to,$&&(window.Artplayer=mo,v("artplayer-style",vo),setTimeout(()=>{mo.LOG_VERSION&&console.log(`%c ArtPlayer %c ${mo.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),ho}); diff --git a/packages/artplayer/dist/artplayer.mjs b/packages/artplayer/dist/artplayer.mjs index 637498faf..4cbf30f51 100644 --- a/packages/artplayer/dist/artplayer.mjs +++ b/packages/artplayer/dist/artplayer.mjs @@ -1031,6 +1031,155 @@ const utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert userAgent, vttToBlob }, Symbol.toStringTag, { value: "Module" })); +function listen(scope, target, name, callback, options = {}) { + const { capture = false, once = false, signal } = options; + if (scope.closed || signal?.aborted) + return () => { + }; + let release = () => { + }; + function listener(event) { + if (once) + release(); + if (scope.closed) + return; + if (typeof callback === "function") + callback.call(this, event); + else + callback.handleEvent(event); + } + target.addEventListener(name, listener, options); + release = scope.add(() => { + try { + target.removeEventListener(name, listener, capture); + } finally { + signal?.removeEventListener("abort", release); + } + }); + signal?.addEventListener("abort", release, { once: true }); + return release; +} +function timeout(scope, callback, delay) { + if (scope.closed) + return () => { + }; + let pending2 = true; + let release = () => { + }; + const timer = setTimeout(() => { + if (!pending2) + return; + release(); + if (!scope.closed) + callback(); + }, delay); + release = scope.add(() => { + pending2 = false; + clearTimeout(timer); + }); + return release; +} +function animationFrame(scope, callback) { + if (scope.closed) + return () => { + }; + let pending2 = true; + let release = () => { + }; + const frame = requestAnimationFrame((time2) => { + if (!pending2) + return; + release(); + if (!scope.closed) + callback(time2); + }); + release = scope.add(() => { + pending2 = false; + cancelAnimationFrame(frame); + }); + return release; +} +function requestController(scope) { + if (typeof AbortController === "undefined") + return void 0; + const controller = new AbortController(); + scope.add(() => { + controller.abort(); + }); + return controller; +} +function wait(scope, delay = 0) { + if (scope.closed) + return Promise.resolve(false); + return new Promise((resolve) => { + let completed = false; + let release = () => { + }; + const timer = setTimeout(() => { + completed = true; + release(); + resolve(true); + }, delay); + release = scope.add(() => { + clearTimeout(timer); + if (!completed) + resolve(false); + }); + }); +} +const handled = /* @__PURE__ */ new WeakSet(); +function claimKey(event) { + handled.add(event); + event.preventDefault(); +} +function isClaimedKey(event) { + return handled.has(event); +} +function plainKey(event) { + return !event.altKey && !event.ctrlKey && !event.metaKey && !event.isComposing && event.keyCode !== 229; +} +function keyboardButton(scope, element, activate = () => element.click(), active2 = () => true) { + if (scope.closed) + return; + if (!element.hasAttribute("role")) + element.setAttribute("role", "button"); + if (!element.hasAttribute("tabindex")) + element.tabIndex = 0; + let space = false; + const enabled = () => active2() && element.getAttribute("aria-disabled") !== "true" && !element.hasAttribute("disabled"); + const own = (event) => (event.composedPath()[0] || event.target) === element; + listen(scope, element, "keydown", (value) => { + const event = value; + if (!own(event) || !plainKey(event) || event.defaultPrevented) + return; + if (event.key === "Enter") { + claimKey(event); + if (!event.repeat && enabled()) + activate(); + } else if (event.key === " ") { + claimKey(event); + if (!event.repeat && enabled()) + space = true; + } + }); + listen(scope, element, "keyup", (value) => { + const event = value; + if (event.key !== " ") + return; + const armed = space; + space = false; + if (armed && own(event) && plainKey(event) && !event.defaultPrevented && enabled() && element.ownerDocument.activeElement === element) { + claimKey(event); + activate(); + } + }); + listen(scope, element, "blur", () => { + space = false; + }); + scope.add(() => { + space = false; + }); +} function renderEntry(element, parent, kind, name, id2, option) { addClass(element, `art-${kind}`); addClass(element, `art-${kind}-${name}`); @@ -1054,6 +1203,63 @@ function appendElement(parent, child) { function queryElement(selector, parent) { return parent.querySelector(selector); } +const owned = /* @__PURE__ */ new WeakSet(); +function focusPlayer(art) { + const player = art.template.$player; + if (isClosing(art) || !player.isConnected) + return; + if (!player.hasAttribute("tabindex")) { + player.setAttribute("tabindex", "-1"); + if (!owned.has(player)) { + owned.add(player); + getScope(art).add(() => { + owned.delete(player); + if (player.getAttribute("tabindex") === "-1") + player.removeAttribute("tabindex"); + }); + } + } + player.focus({ preventScroll: true }); +} +const pending$1 = /* @__PURE__ */ new WeakSet(); +const focusable = "[tabindex],button,input,select,textarea,a[href],[contenteditable]"; +function targetIn(element) { + const targets = [element, ...element.querySelectorAll(focusable)]; + return targets.find((target) => { + if (!target.matches(focusable) || target.tabIndex < 0 || target.matches(":disabled") || target.closest("[inert]") || target.getAttribute("aria-disabled") === "true" || !target.getClientRects().length) + return false; + const style = target.ownerDocument.defaultView?.getComputedStyle(target); + return style?.visibility !== "hidden" && style?.visibility !== "collapse"; + }); +} +function captureComponentFocus(owner, element, replacement) { + const doc = element?.ownerDocument; + const focused = doc?.activeElement; + if (!["control", "contextmenu"].includes(owner.name ?? "") || pending$1.has(owner) || !element || !doc || !focused || !element.contains(focused)) + return () => { + }; + const player = owner.art.template.$player; + const controls = Array.from(player.querySelectorAll(`.art-${owner.name}`)); + const index = controls.indexOf(element); + const neighbors = [...controls.slice(index + 1), ...controls.slice(0, index).reverse()]; + pending$1.add(owner); + return () => { + pending$1.delete(owner); + if (isClosing(owner.art) || !player.isConnected || doc.activeElement !== doc.body) + return; + const next = replacement ? owner.cache.get(replacement)?.$ref : void 0; + for (const candidate of [...next ? [next] : [], ...neighbors]) { + if (!player.contains(candidate)) + continue; + const target = targetIn(candidate); + if (target) { + target.focus({ preventScroll: true }); + return; + } + } + focusPlayer(owner.art); + }; +} const a = "array"; const b = "boolean"; const s = "string"; @@ -1228,6 +1434,9 @@ class Component { if (scope.closed) return; if (option.click) { + const actionable = this.name === "control" && !option.selector || this.name === "contextmenu" && !$ref.querySelector("[data-value]"); + if (actionable && !$ref.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")) + keyboardButton(scope, $ref); const cleanup = this.art.events.proxy($ref, "click", (event) => { if (scope.closed) return; @@ -1269,6 +1478,7 @@ class Component { const item = this.cache.get(name); if (removing.has(item)) return; + const restoreFocus = captureComponentFocus(this, item.$ref); removing.add(item); try { if (item.option.beforeUnmount) @@ -1284,15 +1494,21 @@ class Component { } } finally { removing.delete(item); + restoreFocus(); } } update(option) { - if (this.cache.has(option.name)) { - const item = this.cache.get(option.name); - option = Object.assign(item.option, option); - this.remove(option.name); + const restoreFocus = captureComponentFocus(this, this.cache.get(option.name)?.$ref, option.name); + try { + if (this.cache.has(option.name)) { + const item = this.cache.get(option.name); + option = Object.assign(item.option, option); + this.remove(option.name); + } + return this.add(option); + } finally { + restoreFocus(); } - return this.add(option); } } function assignAlias(owner, name, value) { @@ -1302,6 +1518,22 @@ function assignAlias(owner, name, value) { else aliases[name] = value; } +function updateChoices(panel) { + for (const item of panel.querySelectorAll("[data-value]")) + item.setAttribute("aria-pressed", String(item.classList.contains("art-current"))); +} +function keyboardChoices(panel, label) { + const scope = entryScope(panel); + if (scope.closed) + return; + panel.setAttribute("role", "group"); + panel.setAttribute("aria-label", label); + for (const item of panel.querySelectorAll("[data-value]")) { + keyboardButton(scope, item); + item.setAttribute("aria-label", `${label}: ${item.textContent?.trim() ?? ""}`); + } + updateChoices(panel); +} function aspectRatio$2(option) { return (art) => { const { @@ -1311,9 +1543,10 @@ function aspectRatio$2(option) { const html2 = ASPECT_RATIO.map( (item) => `${item === "default" ? i18n.get("Default") : item}` ).join(""); + const label = i18n.get("Aspect Ratio"); return { ...option, - html: `${i18n.get("Aspect Ratio")}: ${html2}`, + html: `${label}: ${html2}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : void 0; if (value) { @@ -1327,10 +1560,12 @@ function aspectRatio$2(option) { if ($default) { inverseClass($default, "art-current"); } + keyboardChoices($panel, label); on("aspectRatio", (value) => { const $current = Array.from($panel.querySelectorAll("span")).find((item) => item.dataset.value === value); if ($current) { inverseClass($current, "art-current"); + updateChoices($panel); } }); } @@ -1353,9 +1588,10 @@ function flip$2(option) { constructor: { FLIP } } = art; const html2 = FLIP.map((item) => `${i18n.get(capitalize(item))}`).join(""); + const label = i18n.get("Video Flip"); return { ...option, - html: `${i18n.get("Video Flip")}: ${html2}`, + html: `${label}: ${html2}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : void 0; if (value) { @@ -1369,10 +1605,12 @@ function flip$2(option) { if ($default) { inverseClass($default, "art-current"); } + keyboardChoices($panel, label); on("flip", (value) => { const $current = Array.from($panel.querySelectorAll("span")).find((item) => item.dataset.value === value); if ($current) { inverseClass($current, "art-current"); + updateChoices($panel); } }); } @@ -1389,6 +1627,158 @@ function info(option) { } }); } +const origins$1 = /* @__PURE__ */ new WeakMap(); +function setOverlayOrigin(overlay, origin) { + if (origin) + origins$1.set(overlay, origin); + else + origins$1.delete(overlay); +} +function resolveFocusOrigin(target) { + const visited = /* @__PURE__ */ new Set(); + let current2 = target; + while (!visited.has(current2)) { + visited.add(current2); + let element = current2; + let origin; + while (element && !origin) { + origin = origins$1.get(element); + element = element.parentElement; + } + if (!origin) + return current2; + current2 = origin; + } + return target; +} +function editable$1(target) { + const element = target; + return !!element && (["INPUT", "TEXTAREA", "SELECT"].includes(element.tagName) || element.isContentEditable); +} +function available$1(element) { + const visibility = element.ownerDocument.defaultView?.getComputedStyle(element).visibility; + return element.isConnected && !element.matches(":disabled") && !element.closest("[inert]") && element.getAttribute("aria-disabled") !== "true" && element.getClientRects().length > 0 && visibility !== "hidden" && visibility !== "collapse"; +} +function contextmenuKeyboard(menu, open) { + const { art } = menu; + const { $player, $contextmenu } = art.template; + const scope = entryScope($contextmenu); + const active2 = () => !scope.closed && !isClosing(art); + let origin; + let hadFocus = false; + let prefix = ""; + let typedAt = 0; + const capture = () => { + const focused = $player.ownerDocument.activeElement; + origin = focused && $player.contains(focused) ? resolveFocusOrigin(focused) : $player; + setOverlayOrigin($contextmenu, origin); + }; + const targets = () => Array.from($contextmenu.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]")).filter((element) => element.tabIndex >= 0 && available$1(element)); + const label = art.i18n.get("Context Menu"); + if (!active2()) + return { pointer: () => false }; + $contextmenu.setAttribute("role", "group"); + $contextmenu.setAttribute("aria-label", label); + const changed = (show) => { + if (!active2()) + return; + if (show) { + if (!$contextmenu.contains($player.ownerDocument.activeElement)) + capture(); + return; + } + const focused = $player.ownerDocument.activeElement; + const restore = $contextmenu.contains(focused) || hadFocus && focused === $player.ownerDocument.body; + const previous = origin; + origin = void 0; + hadFocus = false; + prefix = ""; + setOverlayOrigin($contextmenu); + if (!restore) + return; + if (previous && $player.contains(previous) && available$1(previous)) + previous.focus({ preventScroll: true }); + if ($player.ownerDocument.activeElement === $player.ownerDocument.body || $contextmenu.contains($player.ownerDocument.activeElement)) + focusPlayer(art); + }; + art.on("contextmenu", changed); + scope.add(() => { + art.off("contextmenu", changed); + setOverlayOrigin($contextmenu); + }); + listen(scope, $contextmenu, "focusin", () => { + hadFocus = true; + }); + let pending2 = false; + listen(scope, $contextmenu, "focusout", (input) => { + if ($contextmenu.contains(input.relatedTarget) || pending2) + return; + pending2 = true; + timeout(scope, () => { + pending2 = false; + if (active2() && menu.show && !$contextmenu.contains($player.ownerDocument.activeElement)) + menu.show = false; + }, 0); + }); + listen(scope, $player, "keydown", (input) => { + const event = input; + if (!active2() || !plainKey(event) || event.defaultPrevented) + return; + const opening = event.key === "ContextMenu" || event.key === "F10" && event.shiftKey; + if (opening && art.constructor.CONTEXTMENU && !editable$1(event.target)) { + claimKey(event); + capture(); + const rect = event.target.getBoundingClientRect(); + open(rect.left, rect.bottom); + if (active2() && menu.show) + targets()[0]?.focus({ preventScroll: true }); + return; + } + if (!menu.show || !$contextmenu.contains(event.target)) + return; + if (event.key === "Escape") { + claimKey(event); + menu.show = false; + return; + } + if (event.key === "Tab") { + menu.show = false; + return; + } + if (editable$1(event.target)) + return; + const items = targets(); + const index = items.indexOf(event.target); + let target; + if (event.key === "ArrowDown" || event.key === "ArrowRight") { + target = items[(index + 1) % items.length]; + } else if (event.key === "ArrowUp" || event.key === "ArrowLeft") { + target = items[(index + items.length - 1) % items.length]; + } else if (event.key === "Home") { + target = items[0]; + } else if (event.key === "End") { + target = items[items.length - 1]; + } else if (event.key.length === 1 && event.key !== " ") { + const key = event.key.toLowerCase(); + prefix = Date.now() - typedAt > 700 ? key : prefix + key; + typedAt = Date.now(); + const search = [...prefix].every((letter) => letter === key) ? key : prefix; + target = [...items.slice(index + 1), ...items.slice(0, index + 1)].find((item) => (item.getAttribute("aria-label") || item.textContent || "").trim().toLowerCase().startsWith(search)); + } else { + return; + } + claimKey(event); + target?.focus({ preventScroll: true }); + }); + return { + pointer(event) { + if (!active2() || !art.constructor.CONTEXTMENU || editable$1(event.target)) + return false; + capture(); + return true; + } + }; +} function playbackRate$2(option) { return (art) => { const { @@ -1398,9 +1788,10 @@ function playbackRate$2(option) { const html2 = PLAYBACK_RATE.map( (item) => `${item === 1 ? i18n.get("Normal") : item.toFixed(1)}` ).join(""); + const label = i18n.get("Play Speed"); return { ...option, - html: `${i18n.get("Play Speed")}: ${html2}`, + html: `${label}: ${html2}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : void 0; if (value) { @@ -1413,18 +1804,33 @@ function playbackRate$2(option) { const $default = query('[data-value="1"]', $panel); if ($default) inverseClass($default, "art-current"); + keyboardChoices($panel, label); on("video:ratechange", () => { const $current = Array.from($panel.querySelectorAll("span")).find( (item) => Number(item.dataset.value) === art.playbackRate ); if ($current) { inverseClass($current, "art-current"); + updateChoices($panel); } }); } }; }; } +function positionContextmenu(art, mouseX, mouseY) { + const { $player, $contextmenu } = art.template; + const { height: cHeight, width: cWidth, left: cLeft, top: cTop } = getRect($player); + const { height: mHeight, width: mWidth } = getRect($contextmenu); + let menuLeft = mouseX - cLeft; + let menuTop = mouseY - cTop; + if (mouseX + mWidth > cLeft + cWidth) + menuLeft = cWidth - mWidth; + if (mouseY + mHeight > cTop + cHeight) + menuTop = cHeight - mHeight; + if (!isClosing(art)) + setStyles($contextmenu, { top: `${menuTop}px`, left: `${menuLeft}px` }); +} function version(option) { return { ...option, @@ -1492,27 +1898,21 @@ class Contextmenu extends Component { for (let index = 0; index < option.contextmenu.length; index++) { this.add(option.contextmenu[index]); } + if (isClosing(this.art)) + return; + releaseEntry($contextmenu); + const scope = ownEntry(this.art, $contextmenu); + const open = (x, y) => { + this.show = true; + if (!scope.closed && !isClosing(this.art) && this.show) + positionContextmenu(this.art, x, y); + }; + const keyboard = contextmenuKeyboard(this, open); proxy($player, "contextmenu", (event) => { - if (!this.art.constructor.CONTEXTMENU) + if (!keyboard.pointer(event)) return; event.preventDefault(); - this.show = true; - const mouseX = event.clientX; - const mouseY = event.clientY; - const { height: cHeight, width: cWidth, left: cLeft, top: cTop } = getRect($player); - const { height: mHeight, width: mWidth } = getRect($contextmenu); - let menuLeft = mouseX - cLeft; - let menuTop = mouseY - cTop; - if (mouseX + mWidth > cLeft + cWidth) { - menuLeft = cWidth - mWidth; - } - if (mouseY + mHeight > cTop + cHeight) { - menuTop = cHeight - mHeight; - } - setStyles($contextmenu, { - top: `${menuTop}px`, - left: `${menuLeft}px` - }); + open(event.clientX, event.clientY); }); proxy($player, "click", (event) => { if (!includeFromEvent(event, $contextmenu)) { @@ -1524,101 +1924,51 @@ class Contextmenu extends Component { }); } } -function listen(scope, target, name, callback, options = {}) { - const { capture = false, once = false, signal } = options; - if (scope.closed || signal?.aborted) - return () => { - }; - let release = () => { +function focusVisibility(scope, root, show) { + let keyboard = true; + let document2; + let documentScope; + const focused = () => !scope.closed && keyboard && root.contains(root.ownerDocument.activeElement); + const update = () => { + const visible = focused(); + const previous = root.classList.contains("art-keyboard-focus"); + root.classList.toggle("art-keyboard-focus", visible); + if (visible && !previous) + show(); }; - function listener(event) { - if (once) - release(); - if (scope.closed) - return; - if (typeof callback === "function") - callback.call(this, event); - else - callback.handleEvent(event); - } - target.addEventListener(name, listener, options); - release = scope.add(() => { - try { - target.removeEventListener(name, listener, capture); - } finally { - signal?.removeEventListener("abort", release); - } - }); - signal?.addEventListener("abort", release, { once: true }); - return release; -} -function timeout(scope, callback, delay) { - if (scope.closed) - return () => { - }; - let pending2 = true; - let release = () => { + const key = () => { + keyboard = true; + update(); }; - const timer = setTimeout(() => { - if (!pending2) - return; - release(); - if (!scope.closed) - callback(); - }, delay); - release = scope.add(() => { - pending2 = false; - clearTimeout(timer); - }); - return release; -} -function animationFrame(scope, callback) { - if (scope.closed) - return () => { - }; - let pending2 = true; - let release = () => { + const pointer = () => { + keyboard = false; + update(); }; - const frame = requestAnimationFrame((time2) => { - if (!pending2) + const bindDocument = () => { + if (document2 === root.ownerDocument) return; - release(); - if (!scope.closed) - callback(time2); + documentScope?.dispose(); + document2 = root.ownerDocument; + documentScope = scope.child(); + listen(documentScope, document2, "keydown", key, { capture: true }); + listen(documentScope, document2, "mousedown", pointer, { capture: true }); + listen(documentScope, document2, "touchstart", pointer, { capture: true, passive: true }); + }; + bindDocument(); + listen(scope, root, "keydown", key, { capture: true }); + listen(scope, root, "mousedown", pointer, { capture: true }); + listen(scope, root, "touchstart", pointer, { capture: true, passive: true }); + listen(scope, root, "focusin", () => { + bindDocument(); + update(); }); - release = scope.add(() => { - pending2 = false; - cancelAnimationFrame(frame); + listen(scope, root, "focusout", () => { + root.classList.remove("art-keyboard-focus"); }); - return release; -} -function requestController(scope) { - if (typeof AbortController === "undefined") - return void 0; - const controller = new AbortController(); scope.add(() => { - controller.abort(); - }); - return controller; -} -function wait(scope, delay = 0) { - if (scope.closed) - return Promise.resolve(false); - return new Promise((resolve) => { - let completed = false; - let release = () => { - }; - const timer = setTimeout(() => { - completed = true; - release(); - resolve(true); - }, delay); - release = scope.add(() => { - clearTimeout(timer); - if (!completed) - resolve(false); - }); + root.classList.remove("art-keyboard-focus"); }); + return focused; } function airplay$1(option) { return (art) => ({ @@ -1627,6 +1977,7 @@ function airplay$1(option) { mounted: ($control) => { const { proxy } = controlEvents(art, $control); const { icons } = art; + keyboardButton(entryScope($control), $control); appendElement($control, icons.airplay); proxy($control, "click", () => art.airplay()); } @@ -1639,6 +1990,7 @@ function fullscreen(option) { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control); const { icons, i18n } = art; + keyboardButton(entryScope($control), $control); const $fullscreenOn = appendElement($control, icons.fullscreenOn); const $fullscreenOff = appendElement($control, icons.fullscreenOff); setStyle($fullscreenOff, "display", "none"); @@ -1666,6 +2018,7 @@ function fullscreenWeb(option) { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control); const { icons, i18n } = art; + keyboardButton(entryScope($control), $control); const $fullscreenWebOn = appendElement($control, icons.fullscreenWebOn); const $fullscreenWebOff = appendElement($control, icons.fullscreenWebOff); setStyle($fullscreenWebOff, "display", "none"); @@ -1693,6 +2046,7 @@ function pip$1(option) { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control); const { icons, i18n } = art; + keyboardButton(entryScope($control), $control); appendElement($control, icons.pip); proxy($control, "click", () => { art.pip = !art.pip; @@ -1711,6 +2065,7 @@ function playAndPause(option) { const { icons, i18n } = art; const $play = appendElement($control, icons.play); const $pause = appendElement($control, icons.pause); + keyboardButton(entryScope($control), $control, () => (art.playing ? $pause : $play).click()); tooltip($play, i18n.get("Play")); tooltip($pause, i18n.get("Pause")); proxy($play, "click", () => { @@ -1720,10 +2075,12 @@ function playAndPause(option) { art.pause(); }); function showPlay() { + $control.setAttribute("aria-label", i18n.get("Play")); setStyle($play, "display", "flex"); setStyle($pause, "display", "none"); } function showPause() { + $control.setAttribute("aria-label", i18n.get("Pause")); setStyle($play, "display", "none"); setStyle($pause, "display", "flex"); } @@ -1892,6 +2249,165 @@ function installProgressInteractions(art, $control) { }); } } +const directions = /* @__PURE__ */ new Map([["ArrowRight", 1], ["ArrowUp", 1], ["ArrowLeft", -1], ["ArrowDown", -1], ["PageUp", 10], ["PageDown", -10]]); +function keyboardSlider(scope, element, label, read, write, orientation = "horizontal") { + const valid = (range) => [range.min, range.max, range.value, range.step].every(Number.isFinite) && range.max > range.min && range.step > 0; + const clamp2 = (value, range) => Math.min(range.max, Math.max(range.min, value)); + const update = () => { + if (scope.closed) + return; + const range = read(); + const enabled = valid(range); + const value = enabled ? clamp2(range.value, range) : 0; + element.setAttribute("aria-disabled", String(!enabled)); + element.setAttribute("aria-valuemin", String(enabled ? range.min : 0)); + element.setAttribute("aria-valuemax", String(enabled ? range.max : 0)); + element.setAttribute("aria-valuenow", String(value)); + element.setAttribute("aria-valuetext", range.text(value)); + }; + if (scope.closed) + return update; + element.setAttribute("role", "slider"); + element.tabIndex = 0; + element.setAttribute("aria-label", label); + element.setAttribute("aria-orientation", orientation); + listen(scope, element, "keydown", (value) => { + const event = value; + if ((event.composedPath()[0] || event.target) !== element || !plainKey(event) || event.defaultPrevented) + return; + const direction = directions.get(event.key); + if (direction === void 0 && event.key !== "Home" && event.key !== "End") + return; + claimKey(event); + const range = read(); + if (!valid(range)) { + update(); + return; + } + const next = event.key === "Home" ? range.min : event.key === "End" ? range.max : clamp2(range.value, range) + direction * range.step; + write(clamp2(next, range)); + update(); + }); + update(); + return update; +} +const revisions = /* @__PURE__ */ new WeakMap(); +function positionRevision(art) { + return revisions.get(art) || 0; +} +function advancePosition(art) { + revisions.set(art, positionRevision(art) + 1); +} +const POSITION_TOLERANCE = 0.05; +function positionRestoration(art, target, active2) { + let expected; + let observedSeek = false; + let corrected = false; + let manual = false; + let revision = positionRevision(art); + const manualPosition = () => manual || positionRevision(art) !== revision; + const seeking = () => !!art.template?.$video?.seeking; + return { + restore(write = () => { + art.currentTime = target; + }) { + if (!active2() || manualPosition()) + return; + const previousRevision = positionRevision(art); + write(); + revision = positionRevision(art); + if (revision > previousRevision + 1) + manual = true; + if (!active2()) + return; + expected = art.currentTime; + if (!active2() || manualPosition()) + return; + observedSeek = seeking(); + }, + manual() { + manual = true; + }, + ready() { + if (!active2() || seeking()) + return false; + const missed = expected !== void 0 && Math.abs(art.currentTime - expected) > POSITION_TOLERANCE; + if (!manualPosition() && observedSeek && !corrected && expected !== void 0 && missed) { + corrected = true; + if (!active2()) + return false; + art.currentTime = expected; + } + return active2() && !seeking(); + } + }; +} +function installProgressKeyboard(art, element) { + const scope = entryScope(element); + const { on } = controlEvents(art, element); + let revision = 0; + let pending2; + const update = keyboardSlider(scope, element, art.i18n.get("Progress"), () => ({ + min: 0, + max: art.duration, + value: art.currentTime, + step: art.constructor.SEEK_STEP, + text: (value) => `${secondToTime(value)} / ${secondToTime(Number.isFinite(art.duration) && art.duration > 0 ? art.duration : 0)}` + }), (value) => { + const action = ++revision; + pending2?.dispose(); + const operation = scope.child(); + pending2 = operation; + const releaseSource = getSourceScope(art).add(() => { + operation.dispose(); + }); + operation.add(() => { + releaseSource(); + }); + operation.add(() => { + if (pending2 === operation) + pending2 = void 0; + }); + const sourceActive = captureSource(art); + const active2 = () => action === revision && !operation.closed && !isClosing(art) && sourceActive(); + const position = positionRestoration(art, value, active2); + const settle = () => { + if (!active2()) { + operation.dispose(); + return; + } + if (position.ready()) { + operation.dispose(); + update(); + } + }; + for (const name of ["video:seeked", "video:ended"]) { + art.on(name, settle); + operation.add(() => { + art.off(name, settle); + }); + } + try { + art.emit("setBar", "played", value / art.duration); + if (active2()) { + position.restore(() => { + art.seek = value; + }); + } + settle(); + } catch (error2) { + operation.dispose(); + throw error2; + } + }); + on("video:loadedmetadata", update); + on("video:durationchange", update); + on("video:emptied", update); + on("video:timeupdate", update); + on("video:seeking", update); + on("video:seeked", update); + on("video:ended", update); +} function mountProgressView(art, $control) { const { icons, option } = art; const { $player } = art.template; @@ -2016,6 +2532,7 @@ function progress(options) { mounted: ($control) => { mountProgressView(art, $control); installProgressInteractions(art, $control); + installProgressKeyboard(art, $control); } }); } @@ -2026,6 +2543,7 @@ function screenshot$1(option) { mounted: ($control) => { const { proxy } = controlEvents(art, $control); const { icons } = art; + keyboardButton(entryScope($control), $control); appendElement($control, icons.screenshot); proxy($control, "click", () => { silencePromise(art.screenshot()); @@ -2041,11 +2559,14 @@ function setting$1(option) { const { on, proxy } = controlEvents(art, $control); const { icons, i18n } = art; appendElement($control, icons.setting); + keyboardButton(entryScope($control), $control); + $control.setAttribute("aria-expanded", "false"); proxy($control, "click", () => { art.setting.toggle(); art.setting.resize(); }); on("setting", (value) => { + $control.setAttribute("aria-expanded", String(value)); tooltip($control, i18n.get(value ? "Hide Setting" : "Show Setting")); }); } @@ -2082,9 +2603,13 @@ function volume$1(option) { ...option, mounted: ($control) => { const { on, proxy } = controlEvents(art, $control); - const { icons } = art; + const { icons, i18n } = art; const $volume = appendElement($control, icons.volume); const $close = appendElement($control, icons.volumeClose); + for (const element of [$volume, $close]) { + keyboardButton(entryScope($control), element); + element.setAttribute("aria-label", i18n.get("Mute")); + } const $panel = appendElement($control, '
'); const $inner = appendElement($panel, '
'); const $value = appendElement($inner, `
`); @@ -2092,12 +2617,32 @@ function volume$1(option) { const $handle = appendElement($slider, `
`); const $loaded = appendElement($handle, `
`); const $indicator = appendElement($slider, `
`); + const scope = entryScope($control); + let revision = 0; + const updateSlider = keyboardSlider(scope, $slider, i18n.get("Volume"), () => ({ + min: 0, + max: 100, + value: art.muted ? 0 : art.volume * 100, + step: art.constructor.VOLUME_STEP * 100, + text: (value) => `${Math.round(value)}%` + }), (value) => { + const action = ++revision; + art.muted = false; + if (action === revision && !scope.closed && !isClosing(art)) + art.volume = value / 100; + }, "vertical"); function getVolumeFromEvent(event) { const { top, height } = getRect($slider); return 1 - (event.clientY - top) / height; } function update() { - if (art.muted || art.volume === 0) { + updateSlider(); + const focused = $control.ownerDocument.activeElement; + const muted = art.muted || art.volume === 0; + const visible = muted ? $close : $volume; + $volume.setAttribute("aria-pressed", String(art.muted)); + $close.setAttribute("aria-pressed", String(art.muted)); + if (muted) { setStyle($volume, "display", "none"); setStyle($close, "display", "flex"); setStyle($indicator, "top", "100%"); @@ -2111,6 +2656,8 @@ function volume$1(option) { setStyle($loaded, "top", `${100 - percentage}%`); $value.textContent = String(Math.floor(percentage)); } + if ((focused === $volume || focused === $close) && focused !== visible) + visible.focus({ preventScroll: true }); } update(); on("video:volumechange", update); @@ -2287,6 +2834,189 @@ function trackSelection(event, active2) { function captureSelection(event) { return event && selections.get(event) || (() => true); } +const interactive = "button,input,select,textarea,a[href],[tabindex],[contenteditable]"; +function selectorKeyboard(scope, owner, value, list, label) { + if (scope.closed) + return () => { + }; + const items = Array.from(list.children); + const complex = items.some((item) => item.querySelector(interactive)); + list.setAttribute("role", complex ? "group" : "listbox"); + list.setAttribute("aria-label", label); + let hovered = false; + let opened = false; + let dismissed = false; + let prefix = ""; + let typedAt = 0; + const expanded = () => items.length > 0 && (opened || hovered && !dismissed); + const trigger = () => value.querySelector('button,a[href],[role="button"]') || value; + const refresh = (restore = false) => { + if (scope.closed) + return; + const target = trigger(); + if (value.querySelector(interactive)) { + value.removeAttribute("role"); + value.removeAttribute("tabindex"); + } else { + value.setAttribute("role", "button"); + value.tabIndex = 0; + } + if (target !== value) { + value.removeAttribute("aria-haspopup"); + value.removeAttribute("aria-expanded"); + value.removeAttribute("aria-disabled"); + } + if (complex) + target.removeAttribute("aria-haspopup"); + else + target.setAttribute("aria-haspopup", "listbox"); + target.setAttribute("aria-expanded", String(expanded())); + target.setAttribute("aria-disabled", String(items.length === 0)); + if (restore && value.isConnected && value.ownerDocument.activeElement === value.ownerDocument.body) + target.focus({ preventScroll: true }); + }; + const visibility = (state2, hide = false) => { + opened = state2; + dismissed = hide; + owner.classList.toggle("art-selector-open", state2); + owner.classList.toggle("art-selector-dismissed", hide); + refresh(); + }; + const focus = (item) => { + if (!item || scope.closed) + return; + const target = item.querySelector(interactive) || item; + target.focus({ preventScroll: true }); + if (!scope.closed) + item.scrollIntoView({ block: "nearest", inline: "nearest" }); + }; + const open = (last = false) => { + if (scope.closed || !items.length) + return; + visibility(true); + prefix = ""; + focus(items.find((item) => item.classList.contains("art-current")) || items[last ? items.length - 1 : 0]); + }; + const close2 = () => { + if (scope.closed) + return; + const restore = list.contains(owner.ownerDocument.activeElement); + visibility(false, true); + prefix = ""; + if (restore && value.isConnected) + trigger().focus({ preventScroll: true }); + }; + keyboardButton(scope, value, () => { + value.click(); + if (owner.ownerDocument.activeElement === value) + open(); + }); + refresh(); + for (const item of items) { + const selected = item.classList.contains("art-current"); + if (!complex) { + item.setAttribute("role", "option"); + item.setAttribute("aria-selected", String(selected)); + } else { + item.setAttribute("aria-current", String(selected)); + } + if (!item.querySelector(interactive)) { + item.tabIndex = -1; + keyboardButton(scope, item, () => { + item.click(); + close2(); + }); + } + } + listen(scope, value, "keydown", (input) => { + const event = input; + if (!plainKey(event) || event.defaultPrevented || event.target !== value && event.target !== trigger()) + return; + if (event.key === "ArrowDown" || event.key === "ArrowUp") { + claimKey(event); + open(event.key === "ArrowUp"); + } else if (event.key === "Escape" && expanded()) { + claimKey(event); + close2(); + } + }); + listen(scope, value, "click", (event) => { + if (event.isTrusted && event.detail === 0 && trigger() !== value) + open(); + }); + listen(scope, list, "keydown", (input) => { + const event = input; + if (!plainKey(event) || event.defaultPrevented) + return; + if (event.key === "Escape") { + claimKey(event); + close2(); + return; + } + const index = items.indexOf(event.target); + if (index < 0) + return; + if (event.key.length !== 1) + prefix = ""; + let next; + switch (event.key) { + case "ArrowDown": + next = Math.min(index + 1, items.length - 1); + break; + case "ArrowUp": + next = Math.max(index - 1, 0); + break; + case "Home": + next = 0; + break; + case "End": + next = items.length - 1; + break; + case "ArrowLeft": + case "ArrowRight": + claimKey(event); + return; + default: { + if (event.key.length !== 1 || event.key === " ") + return; + const now = Date.now(); + prefix = now - typedAt < 500 ? prefix + event.key.toLocaleLowerCase() : event.key.toLocaleLowerCase(); + typedAt = now; + const query2 = [...prefix].every((char) => char === prefix[0]) ? prefix[0] : prefix; + for (let offset = 1; offset <= items.length; offset++) { + const candidate = (index + offset) % items.length; + if (items[candidate].textContent?.trim().toLocaleLowerCase().startsWith(query2)) { + next = candidate; + break; + } + } + } + } + claimKey(event); + if (next !== void 0) + focus(items[next]); + }); + listen(scope, list, "click", (event) => { + if (event.isTrusted && event.detail === 0) + close2(); + }); + listen(scope, owner, "mouseenter", () => { + hovered = true; + visibility(opened); + }); + listen(scope, owner, "mouseleave", () => { + hovered = false; + visibility(list.contains(owner.ownerDocument.activeElement)); + }); + listen(scope, owner, "focusout", (event) => { + if (!owner.contains(event.relatedTarget)) + visibility(false, true); + }); + scope.add(() => { + owner.classList.remove("art-selector-open", "art-selector-dismissed"); + }); + return refresh; +} const bindings$1 = /* @__PURE__ */ new WeakMap(); function bind(item, binding) { const previous = bindings$1.get(item); @@ -2304,13 +3034,17 @@ function setHTML(element, value) { function checkSelector(target) { if (!target) return; + const restore = target.$control_value.contains(target.$control_value.ownerDocument.activeElement); setHTML(target.$control_value, target.html); for (let index = 0; index < target.$control_option.length; index++) { const item = target.$control_option[index]; item.default = item === target; + const element = item.$control_item; + element.setAttribute(element.getAttribute("role") === "option" ? "aria-selected" : "aria-current", String(item.default)); if (item.default) inverseClass(item.$control_item, "art-current"); } + bindings$1.get(target)?.refresh?.(restore); } function renderSelector(art, check2, option, $ref, events) { const { proxy } = art.events; @@ -2352,8 +3086,11 @@ function renderSelector(art, check2, option, $ref, events) { return; if (option.onSelect) { const value = await option.onSelect.call(art, item, item.$control_item, event2); - if (active2()) + if (active2()) { + const restore = $value.contains($value.ownerDocument.activeElement); setHTML($value, value); + bindings$1.get(item)?.refresh?.(restore); + } } } catch (error2) { console.warn("ArtPlayer selector failed:", error2); @@ -2362,6 +3099,9 @@ function renderSelector(art, check2, option, $ref, events) { } }); events.push(event); + const refresh = selectorKeyboard(scope, $ref, $value, $list, String(option.tooltip || option.name || $value.textContent || art.i18n.get("Open"))); + for (const item of selector) + bindings$1.get(item).refresh = refresh; } class Control extends Component { constructor(art) { @@ -2371,8 +3111,21 @@ class Control extends Component { this.timer = Date.now(); const { constructor } = art; const { $player, $bottom } = this.art.template; - ownEntry(art, $bottom); - const { on } = controlEvents(art, $bottom); + const scope = ownEntry(art, $bottom); + const keyboardFocused = focusVisibility(scope, $player, () => { + this.show = true; + }); + const { on, proxy } = controlEvents(art, $bottom); + proxy($player, "focusin", (event) => { + art.isFocus = true; + art.isInput = event.target?.tagName === "INPUT"; + }); + proxy($player, "focusout", (event) => { + if (!$player.contains(event.relatedTarget)) { + art.isFocus = false; + art.isInput = false; + } + }); on("mousemove", () => { if (!isMobile) { this.show = true; @@ -2389,7 +3142,7 @@ class Control extends Component { this.isHover = includeFromEvent(event, $bottom); }); on("video:timeupdate", () => { - if (!art.setting.show && !this.isHover && !art.isInput && art.playing && this.show && Date.now() - this.timer >= constructor.CONTROL_HIDE_TIME) { + if (!art.setting.show && !this.isHover && !art.isInput && !keyboardFocused() && art.playing && this.show && Date.now() - this.timer >= constructor.CONTROL_HIDE_TIME) { this.show = false; } }); @@ -2966,7 +3719,7 @@ function editable(target) { return target.isContentEditable; } function acceptsHotkey(event, fallback) { - if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.isComposing || event.keyCode === 229) + if (isClaimedKey(event) || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.isComposing || event.keyCode === 229) return false; const doc = eventDocument(event, fallback); let active2 = asElement(doc.activeElement); @@ -2975,6 +3728,13 @@ function acceptsHotkey(event, fallback) { if (active2 && editable(active2)) return false; const first = asElement(event.composedPath?.()[0]) || asElement(event.target); + const enter = event.key === "Enter" || event.code === "Enter" || event.code === "NumpadEnter"; + const activation = enter || event.key === " " || event.code === "Space"; + if (activation) { + const selector = `button,summary,[role="button"],[role="switch"]${enter ? ",a[href]" : ""}`; + if (first?.closest?.(selector) || active2?.closest?.(selector)) + return false; + } return !first || !editable(first); } const states$4 = /* @__PURE__ */ new WeakMap(); @@ -3059,6 +3819,11 @@ function publishLanguage(name, value) { } } const zhCn = { + "Context Menu": "快捷菜单", + "Lock": "锁定", + "Back": "返回", + "Settings": "设置", + "Progress": "播放进度", "Video Info": "统计信息", "Close": "关闭", "Video Load Failed": "加载失败", @@ -3182,6 +3947,61 @@ class Icons { } } } +const origins = /* @__PURE__ */ new WeakMap(); +function infoKeyboard(art, scope, close2) { + const { $player, $info, $infoClose } = art.template; + if (!$info) + return; + const active2 = () => !scope.closed && !isClosing(art); + const visible = () => $player.classList.contains("art-info-show"); + const closeLabel = art.i18n.get("Close"); + if (!active2()) + return; + const groupLabel = art.i18n.get("Video Info"); + if (!active2()) + return; + $infoClose.setAttribute("aria-label", closeLabel); + $info.setAttribute("role", "group"); + $info.setAttribute("aria-label", groupLabel); + keyboardButton(scope, $infoClose, () => $infoClose.click(), visible); + listen(scope, $info, "keydown", (input) => { + const event = input; + if (active2() && visible() && plainKey(event) && !event.defaultPrevented && event.key === "Escape") { + claimKey(event); + close2(); + } + }); + const changed = (show) => { + if (!active2()) + return; + const doc = $player.ownerDocument; + const focused = doc.activeElement; + if (show) { + if (!$info.contains(focused)) { + origins.delete(art); + if (focused && $player.contains(focused)) { + origins.set(art, resolveFocusOrigin(focused)); + if ($player.classList.contains("art-keyboard-focus")) + $infoClose.focus({ preventScroll: true }); + } + } + } else { + const origin = origins.get(art); + origins.delete(art); + if (!$info.contains(focused)) + return; + const visibility = origin && doc.defaultView?.getComputedStyle(origin).visibility; + if (origin?.isConnected && $player.contains(origin) && origin.getClientRects().length && visibility !== "hidden" && visibility !== "collapse" && !origin.matches(":disabled") && !origin.closest("[inert]") && origin.getAttribute("aria-disabled") !== "true") + origin.focus({ preventScroll: true }); + else + focusPlayer(art); + } + }; + art.on("info", changed); + scope.add(() => { + art.off("info", changed); + }); +} function pollInfo(art, scope, close2) { const active2 = () => !scope.closed && !isClosing(art); const fail = (error2) => { @@ -3207,6 +4027,7 @@ function pollInfo(art, scope, close2) { scope.add(() => { art.off("destroy", destroy); }); + infoKeyboard(art, scope, close2); const loop = () => { try { for (const item of items) { @@ -3484,7 +4305,7 @@ function airplayMix(art) { proxy, template: { $video } } = art; - let available = true; + let available2 = true; const supported = window.WebKitPlaybackTargetAvailabilityEvent; if (isClosing(art)) return; @@ -3497,15 +4318,15 @@ function airplayMix(art) { return; switch (event.availability) { case "available": - available = true; + available2 = true; break; case "not-available": - available = false; + available2 = false; break; } }); } else { - available = false; + available2 = false; } if (isClosing(art)) return; @@ -3513,7 +4334,7 @@ function airplayMix(art) { value() { if (isClosing(art)) return; - if (available) { + if (available2) { const picker2 = $video.webkitShowPlaybackTargetPicker; if (isClosing(art)) return; @@ -3642,13 +4463,6 @@ function cssVarMix(art) { } }); } -const revisions = /* @__PURE__ */ new WeakMap(); -function positionRevision(art) { - return revisions.get(art) || 0; -} -function advancePosition(art) { - revisions.set(art, positionRevision(art) + 1); -} function currentTimeMix(art) { const { $video } = art.template; def(art, "currentTime", { @@ -4363,6 +5177,14 @@ function fullscreenMix(art) { art.off("video:loadedmetadata", metadata); }); } +function captureMovedFocus(root) { + const focused = root.ownerDocument?.activeElement; + const inside = focused && root.contains(focused); + return () => { + if (inside && focused.isConnected && root.contains(focused) && focused.ownerDocument.activeElement === focused.ownerDocument.body) + focused.focus({ preventScroll: true }); + }; +} function capturePlacement(node) { return { node, parent: node.parentNode, next: node.nextSibling }; } @@ -4415,6 +5237,7 @@ function webFullscreen(art) { return; const current2 = ++revision; const active2 = () => current2 === revision && !isClosing(art); + const restoreFocus = captureMovedFocus($player); if (value) { if (!saved) saved = { placement: capturePlacement($player), style: $player.getAttribute("style") }; @@ -4431,10 +5254,15 @@ function webFullscreen(art) { $player.style.height = "100%"; $player.classList.add("art-fullscreen-web"); } catch (error2) { - if (active2() && restore(snapshot, active2)) + if (active2() && restore(snapshot, active2)) { saved = void 0; + restoreFocus(); + } throw error2; } + if (!active2()) + return; + restoreFocus(); if (!active2()) return; art.emit("fullscreenWeb", true); @@ -4446,6 +5274,9 @@ function webFullscreen(art) { } else { $player.classList.remove("art-fullscreen-web"); } + if (!active2()) + return; + restoreFocus(); if (!active2()) return; art.emit("fullscreenWeb", false); @@ -4471,6 +5302,37 @@ function loadedMix(art) { get: () => $video.buffered.length ? $video.buffered.end($video.buffered.length - 1) : 0 }); } +function miniFocus(art) { + const player = art.template.$player; + let origin; + return { + entering() { + const doc = player.ownerDocument; + const focused = doc.activeElement; + const inside = focused && player.contains(focused); + if (!art.template.$mini?.contains(focused)) + origin = inside ? resolveFocusOrigin(focused) : void 0; + const keyboard = inside && player.classList.contains("art-keyboard-focus"); + return (focus) => { + if (keyboard && !isClosing(art) && (doc.activeElement === focused || doc.activeElement === doc.body)) + focus?.(); + }; + }, + leaving(popup) { + const doc = player.ownerDocument; + const inside = popup?.contains(doc.activeElement); + return () => { + if (!inside || isClosing(art) || doc.activeElement !== doc.body && !popup?.contains(doc.activeElement)) + return; + const visible = origin && doc.defaultView?.getComputedStyle(origin).visibility; + if (origin?.isConnected && origin.getClientRects().length && visible !== "hidden" && visible !== "collapse" && origin.getAttribute("aria-disabled") !== "true" && !origin.matches(":disabled") && !origin.closest("[inert]")) + origin.focus({ preventScroll: true }); + else + focusPlayer(art); + }; + } + }; +} function clampMini(left, top, geometry) { const maxLeft = Math.max(0, geometry.viewportWidth - geometry.width); const maxTop = Math.max(0, geometry.viewportHeight - geometry.height); @@ -4566,6 +5428,24 @@ function createMiniView(art, parent, active2, hide) { return; state2.append(play2, pause2); element.append(close2, state2); + keyboardButton(scope, close2, () => close2.click(), active2); + keyboardButton(scope, state2, () => (art.playing ? pause2 : play2).click(), active2); + const closeLabel = art.i18n.get("Close"); + if (scope.closed || isClosing(art)) + return; + close2.setAttribute("aria-label", closeLabel); + const groupLabel = art.i18n.get("Mini Player"); + if (scope.closed || isClosing(art)) + return; + element.setAttribute("role", "group"); + element.setAttribute("aria-label", groupLabel); + listen(scope, element, "keydown", (input) => { + const event = input; + if (active2() && plainKey(event) && !event.defaultPrevented && event.key === "Escape") { + claimKey(event); + hide(); + } + }); listen(scope, close2, "click", hide); listen(scope, play2, "click", () => { silencePromise(art.play()); @@ -4576,6 +5456,10 @@ function createMiniView(art, parent, active2, hide) { const update = () => { if (scope.closed) return; + const label = art.i18n.get(art.playing ? "Pause" : "Play"); + if (scope.closed || isClosing(art)) + return; + state2.setAttribute("aria-label", label); play2.style.display = art.playing ? "none" : "flex"; pause2.style.display = art.playing ? "flex" : "none"; }; @@ -4592,7 +5476,7 @@ function createMiniView(art, parent, active2, hide) { art.template.$mini = element; document2.body.append(element); if (!scope.closed) - return { element, cancelDrag, fresh: true }; + return { element, cancelDrag, fresh: true, focus: () => close2.focus({ preventScroll: true }) }; } catch (error2) { scope.dispose(); if (art.template.$mini === element) @@ -4609,6 +5493,7 @@ function mini(art) { let creating = false; let queued = false; const active2 = () => !isClosing(art) && $player.classList.contains("art-mini"); + const focus = miniFocus(art); function restore() { if (placement) { const saved = placement; @@ -4628,6 +5513,7 @@ function mini(art) { return; const current2 = ++revision; queued = false; + const restoreFocus = focus.leaving(art.template.$mini); restore(); if (isClosing(art) || current2 !== revision) return; @@ -4635,7 +5521,9 @@ function mini(art) { $player.classList.remove("art-mini"); if (art.template.$mini) { art.template.$mini.style.display = "none"; - art.emit("mini", false); + restoreFocus(); + if (!isClosing(art) && current2 === revision) + art.emit("mini", false); } } scope.add(() => { @@ -4655,6 +5543,7 @@ function mini(art) { queued = true; return; } + const enterFocus = focus.entering(); art.state = "mini"; if (isClosing(art) || current2 !== revision) return; @@ -4702,6 +5591,8 @@ function mini(art) { return; art.storage.set("left", position.left); } + if (!isClosing(art) && current2 === revision) + enterFocus(view.focus); if (!isClosing(art) && current2 === revision) art.emit("mini", true); } catch (error2) { @@ -5310,48 +6201,6 @@ function listenSource(scope, art, name, callback, once = true) { }); return guarded; } -const POSITION_TOLERANCE = 0.05; -function positionRestoration(art, target, active2) { - let expected; - let observedSeek = false; - let corrected = false; - let manual = false; - let revision = positionRevision(art); - const manualPosition = () => manual || positionRevision(art) !== revision; - const seeking = () => !!art.template?.$video?.seeking; - return { - restore() { - if (!active2() || manualPosition()) - return; - const previousRevision = positionRevision(art); - art.currentTime = target; - revision = positionRevision(art); - if (revision > previousRevision + 1) - manual = true; - if (!active2()) - return; - expected = art.currentTime; - if (!active2() || manualPosition()) - return; - observedSeek = seeking(); - }, - manual() { - manual = true; - }, - ready() { - if (!active2() || seeking()) - return false; - const missed = expected !== void 0 && Math.abs(art.currentTime - expected) > POSITION_TOLERANCE; - if (!manualPosition() && observedSeek && !corrected && expected !== void 0 && missed) { - corrected = true; - if (!active2()) - return false; - art.currentTime = expected; - } - return active2() && !seeking(); - } - }; -} function switchSource(art, url, currentTime) { return new Promise((resolve, reject) => { if (isClosing(art) || url === art.url) { @@ -6160,6 +7009,97 @@ function fastForward(art) { } }; } +function suspendFocus(scope, root) { + const original = /* @__PURE__ */ new Map(); + const inert = root.hasAttribute("inert"); + const hidden = root.getAttribute("aria-hidden"); + const restore = (element, value) => { + if (element.getAttribute("tabindex") !== "-1") + return; + if (value === null) + element.removeAttribute("tabindex"); + else + element.setAttribute("tabindex", value); + }; + scope.add(() => { + for (const [element, value] of original) + restore(element, value); + original.clear(); + if (!inert && root.getAttribute("inert") === "") + root.removeAttribute("inert"); + if (root.getAttribute("aria-hidden") === "true") { + if (hidden === null) + root.removeAttribute("aria-hidden"); + else + root.setAttribute("aria-hidden", hidden); + } + }); + if (scope.closed) + return; + if (!inert) + root.setAttribute("inert", ""); + root.setAttribute("aria-hidden", "true"); + const update = () => { + if (scope.closed) + return; + for (const [element, value] of original) { + if (!root.contains(element)) { + restore(element, value); + original.delete(element); + } + } + for (const element of root.querySelectorAll("[tabindex],button,input,select,textarea,a[href],[contenteditable]")) { + if (!original.has(element)) { + original.set(element, element.getAttribute("tabindex")); + element.setAttribute("tabindex", "-1"); + } + } + }; + update(); + if (typeof MutationObserver !== "undefined") { + const observer = new MutationObserver(update); + observer.observe(root, { childList: true, subtree: true }); + scope.add(() => { + observer.disconnect(); + }); + } +} +function lockKeyboard(art, element, scope, locked) { + let suspension; + const active2 = () => !scope.closed && !isClosing(art); + const label = art.i18n.get("Lock"); + if (!active2()) + return () => { + }; + element.setAttribute("aria-label", label); + keyboardButton(scope, element); + listen(scope, element, "keydown", (input) => { + const event = input; + if (active2() && locked() && plainKey(event) && !event.defaultPrevented && event.key === "Escape") { + claimKey(event); + element.click(); + } + }); + const update = (state2) => { + if (!active2()) + return; + element.setAttribute("aria-pressed", String(state2)); + if (state2 && !suspension) { + const { $player, $bottom } = art.template; + const hiddenFocus = $bottom.contains($bottom.ownerDocument.activeElement) && $player.classList.contains("art-keyboard-focus"); + suspension = scope.child(); + suspendFocus(suspension, $bottom); + if (active2() && hiddenFocus) + element.focus({ preventScroll: true }); + } else if (!state2 && suspension) { + const previous = suspension; + suspension = void 0; + previous.dispose(); + } + }; + update(locked()); + return update; +} function lock(art) { const { layers, @@ -6201,13 +7141,24 @@ function lock(art) { const $unlock = appendElement($el, icons.unlock); if (scope.closed || isClosing(art)) return; - setStyle($lock, "display", "none"); + const updateKeyboard = lockKeyboard(art, $el, scope, getState); + if (scope.closed || isClosing(art)) + return; + if (getState()) { + setStyle($lock, "display", "inline-flex"); + if (!scope.closed && !isClosing(art)) + setStyle($unlock, "display", "none"); + } else { + setStyle($lock, "display", "none"); + } subscribeEntry(art, $el, "lock", (state2) => { if (isClosing(art)) return; setStyle($lock, "display", state2 ? "inline-flex" : "none"); if (!scope.closed && !isClosing(art)) setStyle($unlock, "display", state2 ? "none" : "inline-flex"); + if (!scope.closed && !isClosing(art)) + updateKeyboard(state2); }); }, click() { @@ -6787,6 +7738,170 @@ function flip(art) { } }; } +function available(element) { + const visibility = element.ownerDocument.defaultView?.getComputedStyle(element).visibility; + return element.isConnected && !element.matches(":disabled") && !element.closest("[inert]") && element.getAttribute("aria-disabled") !== "true" && element.getClientRects().length > 0 && visibility !== "hidden" && visibility !== "collapse"; +} +function settingFocusTargets(panel) { + return Array.from(panel.querySelectorAll('[tabindex="0"],button,input,select,textarea,a[href],[contenteditable]')).filter((element) => element.getAttribute("tabindex") !== "-1" && available(element)); +} +function returnSettingFocus(setting2) { + const { art, $parent } = setting2; + const player = art.template.$player; + const doc = $parent.ownerDocument; + const button = art.controls.setting; + if (isClosing(art) || !$parent.contains(doc.activeElement)) + return; + if (button && player.contains(button) && available(button)) + button.focus({ preventScroll: true }); + if (doc.activeElement === doc.body || $parent.contains(doc.activeElement)) + focusPlayer(art); +} +function focusSettingPanel(setting2, preferred, last = false) { + if (!setting2.show || isClosing(setting2.art) || !setting2.active) + return; + const panel = setting2.cache.get(setting2.active); + if (!panel || !settingScopeActive(settingPanelScope(panel))) + return; + const targets = settingFocusTargets(panel); + const selected = panel.querySelector(".art-setting-item.art-current"); + const target = targets.find((element) => preferred === element || preferred?.contains(element)) || (last ? targets[targets.length - 1] : targets.find((element) => selected?.contains(element)) || targets.find((element) => !element.classList.contains("art-setting-item-back")) || targets[0]); + target?.focus({ preventScroll: true }); + if (!isClosing(setting2.art)) + target?.scrollIntoView({ block: "nearest", inline: "nearest" }); +} +function captureSettingFocus(setting2) { + const doc = setting2.$parent.ownerDocument; + const focused = doc.activeElement; + const inside = setting2.$parent.contains(focused); + return (preferred) => { + if (!inside || isClosing(setting2.art)) + return; + if (doc.activeElement === doc.body || doc.activeElement === focused && !focused?.getClientRects().length) + focusSettingPanel(setting2, preferred); + }; +} +function installSettingKeyboard(setting2) { + const { art } = setting2; + const scope = getScope(art).child(); + if (scope.closed) + return; + const doc = () => setting2.$parent.ownerDocument; + let enterLast = false; + const close2 = () => { + setting2.show = false; + if (!scope.closed && !isClosing(art)) + setting2.render(); + }; + const changed = (show) => { + if (scope.closed || isClosing(art)) + return; + if (show) { + if (doc().activeElement === art.controls.setting && art.template.$player.classList.contains("art-keyboard-focus")) + focusSettingPanel(setting2, void 0, enterLast); + } else if (setting2.$parent.contains(doc().activeElement)) { + returnSettingFocus(setting2); + } + }; + art.on("setting", changed); + scope.add(() => { + art.off("setting", changed); + }); + listen(scope, art.template.$player, "keydown", (input) => { + const event = input; + if (!plainKey(event) || event.defaultPrevented || isClosing(art)) + return; + const target = event.target; + if (target === art.controls.setting) { + if (event.key === "ArrowDown" || event.key === "ArrowUp") { + claimKey(event); + if (!setting2.show) { + enterLast = event.key === "ArrowUp"; + try { + setting2.show = true; + } finally { + enterLast = false; + } + } else { + focusSettingPanel(setting2, void 0, event.key === "ArrowUp"); + } + } else if (event.key === "Escape" && setting2.show) { + claimKey(event); + close2(); + } + return; + } + if (!setting2.show || !setting2.$parent.contains(target)) + return; + if (event.key === "Escape") { + claimKey(event); + close2(); + return; + } + const row = target.closest(".art-setting-item"); + if (!row || target !== row && !target.matches('button,a[href],[role="button"]')) + return; + const panel = setting2.active && setting2.cache.get(setting2.active); + if (!panel) + return; + const currentItem = setting2.active?.find((item) => item.$item === row); + if (!settingScopeActive(settingPanelScope(panel)) || currentItem && !settingScopeActive(settingScope(currentItem))) { + if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) + claimKey(event); + return; + } + const targets = settingFocusTargets(panel); + const index = targets.indexOf(target); + if (index < 0) + return; + let next; + switch (event.key) { + case "ArrowDown": + next = Math.min(index + 1, targets.length - 1); + break; + case "ArrowUp": + next = Math.max(index - 1, 0); + break; + case "Home": + next = 0; + break; + case "End": + next = targets.length - 1; + break; + case "ArrowLeft": { + const back = panel.querySelector(".art-setting-item-back"); + claimKey(event); + back?.click(); + return; + } + case "ArrowRight": { + claimKey(event); + if (currentItem?.selector?.length) + target.click(); + return; + } + default: + return; + } + claimKey(event); + if (next !== void 0) + focusSettingPanel(setting2, targets[next]); + }); + let pending2 = false; + listen(scope, setting2.$parent, "focusout", (event) => { + const next = event.relatedTarget; + if (next && (setting2.$parent.contains(next) || next === art.controls.setting)) + return; + if (pending2) + return; + pending2 = true; + timeout(scope, () => { + pending2 = false; + if (!scope.closed && !isClosing(art) && setting2.show && !setting2.$parent.contains(doc().activeElement) && doc().activeElement !== art.controls.setting) + close2(); + }, 0); + }); +} function calculateSettingLayout(input) { const { containerWidth, containerHeight, requestedWidth, rows, rowHeight, controlCenter, bottom, padding } = input; const inset = Math.min(Math.max(0, padding), Math.max(0, containerWidth / 2)); @@ -6913,6 +8028,27 @@ function captureSettingItem(item) { } }; } +function nameSettingRange(item) { + const input = item.$item?.querySelector(".art-setting-range"); + if (input) + input.setAttribute("aria-label", item.$html?.textContent || ""); +} +function settingItemKeyboard(setting2, item, element, kind, scope) { + if (kind === "range") { + nameSettingRange(item); + return; + } + if (element.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")) + return; + if (kind === "switch") { + element.setAttribute("role", "switch"); + element.setAttribute("aria-checked", String(Boolean(item.switch))); + element.setAttribute("aria-disabled", String(!item.onSwitch)); + } else if (kind === "selector" && !item.selector?.length) { + element.setAttribute("aria-current", String(Boolean(item.default))); + } + keyboardButton(scope, element, () => element.click(), () => settingScopeActive(scope) && !isClosing(setting2.art)); +} const generations = /* @__PURE__ */ new WeakMap(); function checkSetting(setting2, target) { if (!target?.$parent) @@ -6920,6 +8056,8 @@ function checkSetting(setting2, target) { target.$parent.tooltip = target.html; setting2.traverse((item) => { item.default = item === target; + if (item.$item) + item.$item.setAttribute("aria-current", String(item.default)); if (item.default && item.$item) inverseClass(item.$item, "art-current"); }, target.$option); @@ -7107,6 +8245,7 @@ function updateSetting(setting2, target) { return item || target; if (!item) return setting2.add(target); + const restoreFocus = captureSettingFocus(setting2); cancelSettingAdd(item); cancelSettingUpdate(item); const restoreItem = captureSettingItem(item); @@ -7156,6 +8295,7 @@ function updateSetting(setting2, target) { } } ]); + restoreFocus(element); } catch (error2) { console.warn("ArtPlayer setting restore failed:", error2); } @@ -7191,6 +8331,7 @@ function updateSetting(setting2, target) { pending.delete(affected); } tree.dispose(); + restoreFocus(item.$item); return item; } catch (error2) { if (current2()) @@ -7209,6 +8350,8 @@ function bindContent(item, key, element) { set(value) { element.innerHTML = ""; append(element, value); + if (key === "html") + nameSettingRange(item); } }); } @@ -7231,6 +8374,10 @@ function createSettingHeader(setting2, item) { append($left, $icon); append($left, item.$parent.html); proxySetting(setting2.art, item.$parent, $item, "click", () => setting2.render(item.$parents), settingPanelScope($panel)); + const scope = settingPanelScope($panel); + if (!$item.querySelector("button,input,select,textarea,a[href],[tabindex],[contenteditable]")) + keyboardButton(scope, $item, () => $item.click(), () => settingScopeActive(scope) && !isClosing(setting2.art)); + $item.setAttribute("aria-label", `${setting2.art.i18n.get("Back")}: ${$item.textContent?.trim() || ""}`); append($panel, $item); } function createSettingItem(setting2, item, isUpdate = false) { @@ -7341,6 +8488,7 @@ function createSettingItem(setting2, item, isUpdate = false) { get: () => $switchValue, set(value) { $switchValue = value; + $item.setAttribute("aria-checked", String(Boolean(value))); if (value) { setStyle($switchOff, "display", "none"); setStyle($switchOn, "display", null); @@ -7417,6 +8565,7 @@ function createSettingItem(setting2, item, isUpdate = false) { configurable: true, get: () => $item }); + settingItemKeyboard(setting2, item, $item, type, scope); if (isUpdate) { if (oldItem?.parentNode) oldItem.replaceWith($item); @@ -7450,6 +8599,7 @@ function createSettingItem(setting2, item, isUpdate = false) { function renderSetting(setting2, option = setting2.option) { if (isClosing(setting2.art)) return; + const restoreFocus = captureSettingFocus(setting2); const cached = setting2.cache.get(option); if (cached && !settingScopeActive(settingPanelScope(cached))) return; @@ -7485,6 +8635,8 @@ function renderSetting(setting2, option = setting2.option) { if (!current2()) return; addClass($panel, "art-setting-panel"); + $panel.setAttribute("role", "group"); + $panel.setAttribute("aria-label", option[0]?.$parent?.$html?.textContent || setting2.art.i18n.get("Settings")); append(setting2.$parent, $panel); inverseClass($panel, "art-current"); if (option[0]?.$parent) @@ -7521,6 +8673,8 @@ function renderSetting(setting2, option = setting2.option) { throw error2; } } + if (currentNavigation()) + restoreFocus(previous?.[0]?.$parent?.$item); } function subtitleOffset(art) { const { i18n, icons, constructor } = art; @@ -7567,6 +8721,7 @@ class Setting extends SettingBase { this.render(); installSettingEvents(this); } + installSettingKeyboard(this); } get builtin() { const result = []; @@ -7604,6 +8759,7 @@ class Setting extends SettingBase { releaseSettingTree(this, item); } remove(name) { + const restoreFocus = captureSettingFocus(this); const item = this.find(name); errorHandle(item, `Can't find [${name}] in the [setting]`); this.traverse((item2) => { @@ -7626,6 +8782,7 @@ class Setting extends SettingBase { } if (failures.length) throw new ResourceCleanupError(failures); + restoreFocus(); } update(target) { return updateSetting(this, target); @@ -7715,7 +8872,7 @@ class Storage { } } } -const css = ".art-video-player {\n --art-theme: #f00;\n --art-font-color: #fff;\n --art-background-color: #000;\n --art-text-shadow-color: rgba(0, 0, 0, 0.5);\n --art-transition-duration: 0.2s;\n --art-padding: 10px;\n --art-border-radius: 3px;\n --art-progress-height: 6px;\n --art-progress-color: rgba(255, 255, 255, 0.25);\n --art-progress-top-gap: 10px;\n --art-hover-color: rgba(255, 255, 255, 0.25);\n --art-loaded-color: rgba(255, 255, 255, 0.25);\n --art-state-size: 80px;\n --art-state-opacity: 0.8;\n --art-bottom-height: 100px;\n --art-bottom-offset: 20px;\n --art-bottom-gap: 5px;\n --art-highlight-width: 8px;\n --art-highlight-color: rgba(255, 255, 255, 0.5);\n --art-control-height: 46px;\n --art-control-opacity: 0.75;\n --art-control-icon-size: 36px;\n --art-control-icon-scale: 1.1;\n --art-volume-height: 120px;\n --art-volume-handle-size: 14px;\n --art-lock-size: 36px;\n --art-indicator-scale: 0;\n --art-indicator-size: 16px;\n --art-fullscreen-web-index: 9999;\n --art-settings-icon-size: 24px;\n --art-settings-max-height: 300px;\n --art-selector-max-height: 300px;\n --art-contextmenus-min-width: 250px;\n --art-subtitle-font-size: 20px;\n --art-subtitle-gap: 5px;\n --art-subtitle-bottom: 15px;\n --art-subtitle-border: #000;\n --art-widget-background: rgba(0, 0, 0, 0.85);\n --art-tip-background: rgba(0, 0, 0, 0.7);\n --art-scrollbar-size: 4px;\n --art-scrollbar-background: rgba(255, 255, 255, 0.25);\n --art-scrollbar-background-hover: rgba(255, 255, 255, 0.5);\n --art-mini-progress-height: 2px;\n}\n.art-bg-cover {\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.art-bottom-gradient {\n background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0.4), transparent);\n background-repeat: repeat-x;\n background-position: center bottom;\n}\n.art-backdrop-filter {\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n backdrop-filter: saturate(180%) blur(20px);\n background-color: rgba(0, 0, 0, 0.75) !important;\n}\n.art-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.art-video-player {\n position: relative;\n margin: 0 auto;\n width: 100%;\n height: 100%;\n outline: 0;\n zoom: 1;\n padding: 0;\n text-align: left;\n direction: ltr;\n font-size: 14px;\n line-height: 1.3;\n user-select: none;\n box-sizing: border-box;\n color: var(--art-font-color);\n background-color: var(--art-background-color);\n text-shadow: 0 0 2px var(--art-text-shadow-color);\n font-family: PingFang SC, Helvetica Neue, Microsoft YaHei, Roboto, Arial, sans-serif;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n -ms-high-contrast-adjust: none;\n}\n.art-video-player *,\n.art-video-player *::before,\n.art-video-player *::after {\n box-sizing: border-box;\n}\n.art-video-player ::-webkit-scrollbar {\n width: var(--art-scrollbar-size);\n height: var(--art-scrollbar-size);\n}\n.art-video-player ::-webkit-scrollbar-thumb {\n background-color: var(--art-scrollbar-background);\n}\n.art-video-player ::-webkit-scrollbar-thumb:hover {\n background-color: var(--art-scrollbar-background-hover);\n}\n.art-video-player img {\n max-width: 100%;\n vertical-align: top;\n}\n.art-video-player svg {\n fill: var(--art-font-color);\n}\n.art-video-player a {\n color: var(--art-font-color);\n text-decoration: none;\n}\n.art-icon {\n line-height: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.art-video-player.art-backdrop .art-contextmenus,\n.art-video-player.art-backdrop .art-info,\n.art-video-player.art-backdrop .art-settings,\n.art-video-player.art-backdrop .art-layer-auto-playback,\n.art-video-player.art-backdrop .art-selector-list,\n.art-video-player.art-backdrop .art-volume-inner {\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n backdrop-filter: saturate(180%) blur(20px);\n background-color: rgba(0, 0, 0, 0.75) !important;\n}\n.art-video {\n position: absolute;\n inset: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n}\n.art-poster {\n position: absolute;\n inset: 0;\n z-index: 11;\n width: 100%;\n height: 100%;\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n pointer-events: none;\n}\n.art-video-player .art-subtitle {\n display: none;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n position: absolute;\n z-index: 20;\n width: 100%;\n padding: 0 5%;\n text-align: center;\n pointer-events: none;\n gap: var(--art-subtitle-gap);\n bottom: var(--art-subtitle-bottom);\n font-size: var(--art-subtitle-font-size);\n transition: bottom var(--art-transition-duration) ease;\n text-shadow: var(--art-subtitle-border) 1px 0 1px, var(--art-subtitle-border) 0 1px 1px, var(--art-subtitle-border) -1px 0 1px, var(--art-subtitle-border) 0 -1px 1px, var(--art-subtitle-border) 1px 1px 1px, var(--art-subtitle-border) -1px -1px 1px, var(--art-subtitle-border) 1px -1px 1px, var(--art-subtitle-border) -1px 1px 1px;\n}\n.art-video-player.art-subtitle-show .art-subtitle {\n display: flex;\n}\n.art-video-player.art-control-show .art-subtitle {\n bottom: calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom));\n}\n.art-danmuku {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: hidden;\n}\n.art-video-player .art-layers {\n position: absolute;\n inset: 0;\n z-index: 40;\n width: 100%;\n height: 100%;\n display: none;\n pointer-events: none;\n}\n.art-video-player .art-layers .art-layer {\n pointer-events: auto;\n}\n.art-video-player.art-layer-show .art-layers {\n display: flex;\n}\n.art-video-player .art-mask {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n inset: 0;\n z-index: 50;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-video-player .art-mask .art-state {\n display: flex;\n justify-content: center;\n align-items: center;\n opacity: 0;\n transform: scale(2);\n width: var(--art-state-size);\n height: var(--art-state-size);\n transition: all var(--art-transition-duration) ease;\n}\n.art-video-player.art-mask-show .art-state {\n pointer-events: auto;\n opacity: var(--art-state-opacity);\n transform: scale(1);\n}\n.art-video-player.art-loading-show .art-state {\n display: none;\n}\n.art-video-player .art-loading {\n display: none;\n justify-content: center;\n align-items: center;\n position: absolute;\n inset: 0;\n z-index: 70;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-video-player.art-loading-show .art-loading {\n display: flex;\n}\n.art-video-player.art-loading-show .art-mask {\n display: none;\n}\n.art-video-player .art-bottom {\n position: absolute;\n inset: 0;\n z-index: 60;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n padding: 0 var(--art-padding);\n transition: all var(--art-transition-duration) ease;\n background-size: 100% var(--art-bottom-height);\n background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0.4), transparent);\n background-repeat: repeat-x;\n background-position: center bottom;\n}\n.art-video-player .art-bottom .art-controls,\n.art-video-player .art-bottom .art-progress {\n transform: translateY(var(--art-bottom-offset));\n transition: transform var(--art-transition-duration) ease;\n}\n.art-video-player.art-control-show .art-bottom,\n.art-video-player.art-hover .art-bottom {\n opacity: 1;\n}\n.art-video-player.art-control-show .art-bottom .art-controls,\n.art-video-player.art-hover .art-bottom .art-controls,\n.art-video-player.art-control-show .art-bottom .art-progress,\n.art-video-player.art-hover .art-bottom .art-progress {\n transform: translateY(0);\n}\n.art-bottom .art-progress {\n position: relative;\n z-index: 0;\n cursor: pointer;\n pointer-events: auto;\n padding-top: var(--art-progress-top-gap);\n padding-bottom: var(--art-bottom-gap);\n}\n.art-bottom .art-progress .art-control-progress {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n height: var(--art-progress-height);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner {\n display: flex;\n align-items: center;\n position: relative;\n height: 50%;\n width: 100%;\n transition: height var(--art-transition-duration) ease;\n background-color: var(--art-progress-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-hover-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded {\n position: absolute;\n inset: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-loaded-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played {\n position: absolute;\n inset: 0;\n z-index: 20;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-theme);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n right: auto;\n pointer-events: auto;\n width: var(--art-highlight-width) !important;\n transform: translateX(calc(var(--art-highlight-width) / -2));\n background-color: var(--art-highlight-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n z-index: 40;\n left: 0;\n border-radius: 50%;\n width: var(--art-indicator-size);\n height: var(--art-indicator-size);\n transform: scale(var(--art-indicator-scale));\n margin-left: calc(var(--art-indicator-size) / -2);\n transition: transform var(--art-transition-duration) ease;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon {\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover {\n transform: scale(1.2) !important;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active {\n transform: scale(1) !important;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip {\n transform-origin: bottom center;\n transform: scale(0.5);\n opacity: 0;\n position: absolute;\n z-index: 50;\n top: -25px;\n left: 0;\n padding: 3px 5px;\n line-height: 1;\n font-size: 12px;\n border-radius: var(--art-border-radius);\n white-space: nowrap;\n background-color: var(--art-tip-background);\n transition: transform var(--art-transition-duration) ease, opacity var(--art-transition-duration) ease;\n}\n.art-bottom .art-progress .art-control-thumbnails {\n transform-origin: bottom center;\n transform: scale(0.5);\n opacity: 0;\n position: absolute;\n bottom: calc(var(--art-bottom-gap) + 10px);\n left: 0;\n border-radius: var(--art-border-radius);\n pointer-events: none;\n background-color: var(--art-widget-background);\n transition: transform var(--art-transition-duration) ease, opacity var(--art-transition-duration) ease;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 2px -1px rgba(0, 0, 0, 0.2);\n}\n.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner {\n height: 100%;\n}\n.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator {\n transform: scale(1);\n}\n.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,\n.art-progress-hover .art-bottom .art-progress .art-control-thumbnails {\n transform: scale(1);\n opacity: 1;\n}\n.art-video-player .art-controls {\n position: relative;\n z-index: 10;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n flex-shrink: 0;\n height: auto;\n min-height: var(--art-control-height);\n}\n.art-video-player .art-controls .art-controls-left,\n.art-video-player .art-controls .art-controls-right {\n display: flex;\n flex-wrap: wrap;\n max-width: 100%;\n min-height: var(--art-control-height);\n}\n.art-video-player .art-controls .art-controls-center {\n display: none;\n justify-content: center;\n align-items: center;\n flex: 1;\n height: 100%;\n padding: 0 10px;\n}\n.art-video-player .art-controls .art-controls-right {\n justify-content: flex-end;\n margin-left: auto;\n}\n.art-video-player .art-controls .art-control {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n max-width: 100%;\n cursor: pointer;\n white-space: nowrap;\n opacity: var(--art-control-opacity);\n min-height: var(--art-control-height);\n min-width: var(--art-control-height);\n transition: opacity var(--art-transition-duration) ease;\n}\n.art-video-player .art-controls .art-control .art-icon {\n height: var(--art-control-icon-size);\n width: var(--art-control-icon-size);\n transform: scale(var(--art-control-icon-scale));\n transition: transform var(--art-transition-duration) ease;\n}\n.art-video-player .art-controls .art-control .art-icon:active {\n transform: scale(calc(var(--art-control-icon-scale) * 0.8));\n}\n.art-video-player .art-controls .art-control:hover {\n opacity: 1;\n}\n.art-control-volume {\n position: relative;\n}\n.art-control-volume .art-volume-panel {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n left: 0;\n right: 0;\n padding: 0 5px;\n font-size: 12px;\n text-align: center;\n cursor: default;\n opacity: 0;\n transform: translateY(10px);\n pointer-events: none;\n bottom: var(--art-control-height);\n width: var(--art-control-height);\n height: var(--art-volume-height);\n transition: all var(--art-transition-duration) ease;\n}\n.art-control-volume .art-volume-panel .art-volume-inner {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 10px;\n height: 100%;\n width: 100%;\n padding: 10px 0 12px;\n border-radius: var(--art-border-radius);\n background-color: var(--art-widget-background);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider {\n flex: 1;\n width: 100%;\n display: flex;\n cursor: pointer;\n position: relative;\n justify-content: center;\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle {\n position: relative;\n display: flex;\n justify-content: center;\n width: 2px;\n border-radius: var(--art-border-radius);\n overflow: hidden;\n background-color: rgba(255, 255, 255, 0.25);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n background-color: var(--art-theme);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator {\n position: absolute;\n width: var(--art-volume-handle-size);\n height: var(--art-volume-handle-size);\n margin-top: calc(var(--art-volume-handle-size) / -2);\n flex-shrink: 0;\n transform: scale(1);\n border-radius: 100%;\n background-color: var(--art-theme);\n transition: transform var(--art-transition-duration) ease;\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator {\n transform: scale(0.9);\n}\n.art-control-volume:hover .art-volume-panel {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n.art-video-player .art-notice {\n display: none;\n position: absolute;\n inset: 0;\n z-index: 80;\n width: 100%;\n height: 100%;\n height: auto;\n bottom: auto;\n padding: var(--art-padding);\n pointer-events: none;\n}\n.art-video-player .art-notice .art-notice-inner {\n display: inline-flex;\n padding: 5px;\n line-height: 1;\n border-radius: var(--art-border-radius);\n background-color: var(--art-tip-background);\n}\n.art-video-player.art-notice-show .art-notice {\n display: flex;\n}\n.art-video-player .art-contextmenus {\n display: none;\n flex-direction: column;\n position: absolute;\n z-index: 120;\n padding: 5px 0;\n border-radius: var(--art-border-radius);\n font-size: 12px;\n background-color: var(--art-widget-background);\n min-width: var(--art-contextmenus-min-width);\n}\n.art-video-player .art-contextmenus .art-contextmenu {\n cursor: pointer;\n display: flex;\n padding: 10px 15px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-contextmenus .art-contextmenu span {\n padding: 0 8px;\n}\n.art-video-player .art-contextmenus .art-contextmenu span:hover,\n.art-video-player .art-contextmenus .art-contextmenu span.art-current {\n color: var(--art-theme);\n}\n.art-video-player .art-contextmenus .art-contextmenu:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-contextmenus .art-contextmenu:last-child {\n border-bottom: none;\n}\n.art-video-player.art-contextmenu-show .art-contextmenus {\n display: flex;\n}\n.art-video-player .art-settings {\n display: none;\n flex-direction: column;\n position: absolute;\n z-index: 90;\n left: auto;\n overflow-y: auto;\n overflow-x: hidden;\n border-radius: var(--art-border-radius);\n max-height: var(--art-settings-max-height);\n right: var(--art-padding);\n bottom: var(--art-controls-height, var(--art-control-height));\n transition: all var(--art-transition-duration) ease;\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-settings .art-setting-panel {\n display: none;\n flex-direction: column;\n}\n.art-video-player .art-settings .art-setting-panel.art-current {\n display: flex;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 5px;\n padding: 0 5px;\n cursor: pointer;\n overflow: hidden;\n transition: background-color var(--art-transition-duration) ease;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current {\n color: var(--art-theme);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check {\n visibility: hidden;\n height: 15px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check {\n visibility: visible;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n gap: 5px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n height: var(--art-settings-icon-size);\n width: var(--art-settings-icon-size);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-width: 0;\n max-width: 55%;\n gap: 5px;\n font-size: 12px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(255, 255, 255, 0.5);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-width: 32px;\n height: 24px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range {\n height: 3px;\n width: 80px;\n outline: none;\n appearance: none;\n background-color: rgba(255, 255, 255, 0.2);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item-back {\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.art-video-player.art-setting-show .art-settings {\n display: flex;\n}\n.art-video-player .art-info {\n display: none;\n position: absolute;\n left: var(--art-padding);\n top: var(--art-padding);\n z-index: 100;\n padding: 10px;\n font-size: 12px;\n border-radius: var(--art-border-radius);\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-info .art-info-panel {\n display: flex;\n flex-direction: column;\n gap: 5px;\n}\n.art-video-player .art-info .art-info-panel .art-info-item {\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.art-video-player .art-info .art-info-panel .art-info-item .art-info-title {\n width: 100px;\n text-align: right;\n}\n.art-video-player .art-info .art-info-panel .art-info-item .art-info-content {\n width: 250px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n user-select: all;\n}\n.art-video-player .art-info .art-info-close {\n position: absolute;\n top: 5px;\n right: 5px;\n cursor: pointer;\n}\n.art-video-player.art-info-show .art-info {\n display: flex;\n}\n.art-hide-cursor * {\n cursor: none !important;\n}\n.art-video-player[data-aspect-ratio] {\n overflow: hidden;\n}\n.art-video-player[data-aspect-ratio] .art-video {\n object-fit: fill;\n box-sizing: content-box;\n}\n.art-fullscreen {\n --art-progress-height: 8px;\n --art-indicator-size: 20px;\n --art-control-height: 60px;\n --art-control-icon-scale: 1.3;\n}\n.art-fullscreen-web {\n --art-progress-height: 8px;\n --art-indicator-size: 20px;\n --art-control-height: 60px;\n --art-control-icon-scale: 1.3;\n position: fixed;\n inset: 0;\n z-index: var(--art-fullscreen-web-index);\n width: 100%;\n height: 100%;\n}\n.art-mini-popup {\n position: fixed;\n z-index: 9999;\n width: 320px;\n height: 180px;\n max-width: 100vw;\n max-height: 100vh;\n background: #000;\n border-radius: var(--art-border-radius);\n cursor: move;\n user-select: none;\n overflow: hidden;\n transition: opacity 0.2s ease;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);\n}\n.art-mini-popup svg {\n fill: #fff;\n}\n.art-mini-popup .art-video {\n pointer-events: none;\n}\n.art-mini-popup .art-mini-close {\n position: absolute;\n z-index: 20;\n right: 10px;\n top: 10px;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n.art-mini-popup .art-mini-state {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.2s ease;\n background-color: rgba(0, 0, 0, 0.25);\n}\n.art-mini-popup .art-mini-state .art-icon {\n opacity: 0.75;\n cursor: pointer;\n transform: scale(3);\n pointer-events: auto;\n transition: transform 0.2s ease;\n}\n.art-mini-popup .art-mini-state .art-icon:active {\n transform: scale(2.5);\n}\n.art-mini-popup.art-mini-dragging {\n opacity: 0.9;\n}\n.art-mini-popup:hover .art-mini-close,\n.art-mini-popup:hover .art-mini-state {\n opacity: 1;\n}\n.art-video-player[data-flip='horizontal'] .art-video {\n transform: scaleX(-1);\n}\n.art-video-player[data-flip='vertical'] .art-video {\n transform: scaleY(-1);\n}\n.art-video-player .art-layer-lock {\n display: none;\n justify-content: center;\n align-items: center;\n position: absolute;\n top: 50%;\n border-radius: 50%;\n transform: translateY(-50%);\n height: var(--art-lock-size);\n width: var(--art-lock-size);\n left: var(--art-padding);\n background-color: var(--art-tip-background);\n}\n.art-video-player .art-layer-auto-playback {\n display: none;\n gap: 10px;\n align-items: center;\n position: absolute;\n border-radius: var(--art-border-radius);\n padding: 10px;\n line-height: 1;\n left: var(--art-padding);\n bottom: calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-close {\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-close svg {\n width: 15px;\n height: 15px;\n fill: var(--art-theme);\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-jump {\n color: var(--art-theme);\n cursor: pointer;\n}\n.art-video-player.art-lock .art-subtitle {\n bottom: var(--art-subtitle-bottom) !important;\n}\n.art-video-player.art-mini-progress-bar .art-bottom,\n.art-video-player.art-lock .art-bottom {\n opacity: 1;\n padding: 0;\n background-image: none;\n}\n.art-video-player.art-mini-progress-bar .art-bottom .art-controls,\n.art-video-player.art-lock .art-bottom .art-controls,\n.art-video-player.art-mini-progress-bar .art-bottom .art-progress,\n.art-video-player.art-lock .art-bottom .art-progress {\n transform: translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4));\n}\n.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,\n.art-video-player.art-lock .art-bottom .art-progress-indicator {\n display: none !important;\n}\n.art-video-player.art-control-show .art-layer-lock {\n display: flex;\n}\n.art-control-selector {\n position: relative;\n display: flex;\n justify-content: center;\n}\n.art-control-selector .art-selector-list {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n position: absolute;\n border-radius: var(--art-border-radius);\n overflow-y: auto;\n overflow-x: hidden;\n opacity: 0;\n transform: translateY(10px);\n pointer-events: none;\n bottom: var(--art-control-height);\n max-height: var(--art-selector-max-height);\n background-color: var(--art-widget-background);\n transition: all var(--art-transition-duration) ease;\n}\n.art-control-selector .art-selector-list .art-selector-item {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n padding: 10px 15px;\n flex-shrink: 0;\n line-height: 1;\n}\n.art-control-selector .art-selector-list .art-selector-item:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-control-selector .art-selector-list .art-selector-item:hover,\n.art-control-selector .art-selector-list .art-selector-item.art-current {\n color: var(--art-theme);\n}\n.art-control-selector:hover .art-selector-list {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n.art-video-player {\n /*! Hint.css - v2.7.0 - 2021-10-01\n * https://kushagra.dev/lab/hint/\n * Copyright (c) 2021 Kushagra Gour */\n /*-------------------------------------*\\\n HINT.css - A CSS tooltip library\n \\*-------------------------------------*/\n /**\n * HINT.css is a tooltip library made in pure CSS.\n *\n * Source: https://github.com/chinchang/hint.css\n * Demo: http://kushagragour.in/lab/hint/\n *\n */\n /**\n * source: hint-core.scss\n *\n * Defines the basic styling for the tooltip.\n * Each tooltip is made of 2 parts:\n * 1) body (:after)\n * 2) arrow (:before)\n *\n * Classes added:\n * 1) hint\n */\n /**\n * source: hint-position.scss\n *\n * Defines the positoning logic for the tooltips.\n *\n * Classes added:\n * 1) hint--top\n * 2) hint--bottom\n * 3) hint--left\n * 4) hint--right\n */\n /**\n * set default color for tooltip arrows\n */\n /**\n * top tooltip\n */\n /**\n * bottom tooltip\n */\n /**\n * right tooltip\n */\n /**\n * left tooltip\n */\n /**\n * top-left tooltip\n */\n /**\n * top-right tooltip\n */\n /**\n * bottom-left tooltip\n */\n /**\n * bottom-right tooltip\n */\n /**\n * source: hint-sizes.scss\n *\n * Defines width restricted tooltips that can span\n * across multiple lines.\n *\n * Classes added:\n * 1) hint--small\n * 2) hint--medium\n * 3) hint--large\n *\n */\n /**\n * source: hint-theme.scss\n *\n * Defines basic theme for tooltips.\n *\n */\n /**\n * source: hint-color-types.scss\n *\n * Contains tooltips of various types based on color differences.\n *\n * Classes added:\n * 1) hint--error\n * 2) hint--warning\n * 3) hint--info\n * 4) hint--success\n *\n */\n /**\n * Error\n */\n /**\n * Warning\n */\n /**\n * Info\n */\n /**\n * Success\n */\n /**\n * source: hint-always.scss\n *\n * Defines a persisted tooltip which shows always.\n *\n * Classes added:\n * 1) hint--always\n *\n */\n /**\n * source: hint-rounded.scss\n *\n * Defines rounded corner tooltips.\n *\n * Classes added:\n * 1) hint--rounded\n *\n */\n /**\n * source: hint-effects.scss\n *\n * Defines various transition effects for the tooltips.\n *\n * Classes added:\n * 1) hint--no-animate\n * 2) hint--bounce\n *\n */\n}\n.art-video-player [class*='hint--'] {\n position: relative;\n display: inline-block;\n font-style: normal;\n /**\n * tooltip arrow\n */\n /**\n * tooltip body\n */\n}\n.art-video-player [class*='hint--']:before,\n.art-video-player [class*='hint--']:after {\n position: absolute;\n -webkit-transform: translate3d(0, 0, 0);\n -moz-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n visibility: hidden;\n opacity: 0;\n z-index: 1000000;\n pointer-events: none;\n -webkit-transition: 0.3s ease;\n -moz-transition: 0.3s ease;\n transition: 0.3s ease;\n -webkit-transition-delay: 0ms;\n -moz-transition-delay: 0ms;\n transition-delay: 0ms;\n}\n.art-video-player [class*='hint--']:hover:before,\n.art-video-player [class*='hint--']:hover:after {\n visibility: visible;\n opacity: 1;\n}\n.art-video-player [class*='hint--']:hover:before,\n.art-video-player [class*='hint--']:hover:after {\n -webkit-transition-delay: 100ms;\n -moz-transition-delay: 100ms;\n transition-delay: 100ms;\n}\n.art-video-player [class*='hint--']:before {\n content: '';\n position: absolute;\n background: transparent;\n border: 6px solid transparent;\n z-index: 1000001;\n}\n.art-video-player [class*='hint--']:after {\n background: #000000;\n color: white;\n padding: 8px 10px;\n font-size: 12px;\n font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n line-height: 12px;\n white-space: nowrap;\n}\n.art-video-player [class*='hint--'][aria-label]:after {\n content: attr(aria-label);\n}\n.art-video-player [class*='hint--'][data-hint]:after {\n content: attr(data-hint);\n}\n.art-video-player [aria-label='']:before,\n.art-video-player [aria-label='']:after,\n.art-video-player [data-hint='']:before,\n.art-video-player [data-hint='']:after {\n display: none !important;\n}\n.art-video-player .hint--top-left:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--top-right:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--top:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--bottom-left:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--bottom-right:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--bottom:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--left:before {\n border-left-color: #000000;\n}\n.art-video-player .hint--right:before {\n border-right-color: #000000;\n}\n.art-video-player .hint--top:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top:before,\n.art-video-player .hint--top:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top:after {\n -webkit-transform: translateX(-50%);\n -moz-transform: translateX(-50%);\n transform: translateX(-50%);\n}\n.art-video-player .hint--top:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top:hover:after {\n -webkit-transform: translateX(-50%) translateY(-8px);\n -moz-transform: translateX(-50%) translateY(-8px);\n transform: translateX(-50%) translateY(-8px);\n}\n.art-video-player .hint--bottom:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom:before,\n.art-video-player .hint--bottom:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom:after {\n -webkit-transform: translateX(-50%);\n -moz-transform: translateX(-50%);\n transform: translateX(-50%);\n}\n.art-video-player .hint--bottom:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom:hover:after {\n -webkit-transform: translateX(-50%) translateY(8px);\n -moz-transform: translateX(-50%) translateY(8px);\n transform: translateX(-50%) translateY(8px);\n}\n.art-video-player .hint--right:before {\n margin-left: -11px;\n margin-bottom: -6px;\n}\n.art-video-player .hint--right:after {\n margin-bottom: -14px;\n}\n.art-video-player .hint--right:before,\n.art-video-player .hint--right:after {\n left: 100%;\n bottom: 50%;\n}\n.art-video-player .hint--right:hover:before {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--right:hover:after {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--left:before {\n margin-right: -11px;\n margin-bottom: -6px;\n}\n.art-video-player .hint--left:after {\n margin-bottom: -14px;\n}\n.art-video-player .hint--left:before,\n.art-video-player .hint--left:after {\n right: 100%;\n bottom: 50%;\n}\n.art-video-player .hint--left:hover:before {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--left:hover:after {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--top-left:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top-left:before,\n.art-video-player .hint--top-left:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top-left:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top-left:after {\n -webkit-transform: translateX(-100%);\n -moz-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n.art-video-player .hint--top-left:after {\n margin-left: 12px;\n}\n.art-video-player .hint--top-left:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top-left:hover:after {\n -webkit-transform: translateX(-100%) translateY(-8px);\n -moz-transform: translateX(-100%) translateY(-8px);\n transform: translateX(-100%) translateY(-8px);\n}\n.art-video-player .hint--top-right:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top-right:before,\n.art-video-player .hint--top-right:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top-right:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top-right:after {\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n transform: translateX(0);\n}\n.art-video-player .hint--top-right:after {\n margin-left: -12px;\n}\n.art-video-player .hint--top-right:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top-right:hover:after {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--bottom-left:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom-left:before,\n.art-video-player .hint--bottom-left:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom-left:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom-left:after {\n -webkit-transform: translateX(-100%);\n -moz-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n.art-video-player .hint--bottom-left:after {\n margin-left: 12px;\n}\n.art-video-player .hint--bottom-left:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom-left:hover:after {\n -webkit-transform: translateX(-100%) translateY(8px);\n -moz-transform: translateX(-100%) translateY(8px);\n transform: translateX(-100%) translateY(8px);\n}\n.art-video-player .hint--bottom-right:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom-right:before,\n.art-video-player .hint--bottom-right:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom-right:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom-right:after {\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n transform: translateX(0);\n}\n.art-video-player .hint--bottom-right:after {\n margin-left: -12px;\n}\n.art-video-player .hint--bottom-right:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom-right:hover:after {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--small:after,\n.art-video-player .hint--medium:after,\n.art-video-player .hint--large:after {\n white-space: normal;\n line-height: 1.4em;\n word-wrap: break-word;\n}\n.art-video-player .hint--small:after {\n width: 80px;\n}\n.art-video-player .hint--medium:after {\n width: 150px;\n}\n.art-video-player .hint--large:after {\n width: 300px;\n}\n.art-video-player [class*='hint--'] {\n /**\n * tooltip body\n */\n}\n.art-video-player [class*='hint--']:after {\n text-shadow: 0 -1px 0px black;\n box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);\n}\n.art-video-player .hint--error:after {\n background-color: #b34e4d;\n text-shadow: 0 -1px 0px #592726;\n}\n.art-video-player .hint--error.hint--top-left:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--top-right:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--top:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom-left:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom-right:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--left:before {\n border-left-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--right:before {\n border-right-color: #b34e4d;\n}\n.art-video-player .hint--warning:after {\n background-color: #c09854;\n text-shadow: 0 -1px 0px #6c5328;\n}\n.art-video-player .hint--warning.hint--top-left:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--top-right:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--top:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom-left:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom-right:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--left:before {\n border-left-color: #c09854;\n}\n.art-video-player .hint--warning.hint--right:before {\n border-right-color: #c09854;\n}\n.art-video-player .hint--info:after {\n background-color: #3986ac;\n text-shadow: 0 -1px 0px #1a3c4d;\n}\n.art-video-player .hint--info.hint--top-left:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--top-right:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--top:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom-left:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom-right:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--left:before {\n border-left-color: #3986ac;\n}\n.art-video-player .hint--info.hint--right:before {\n border-right-color: #3986ac;\n}\n.art-video-player .hint--success:after {\n background-color: #458746;\n text-shadow: 0 -1px 0px #1a321a;\n}\n.art-video-player .hint--success.hint--top-left:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--top-right:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--top:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom-left:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom-right:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--left:before {\n border-left-color: #458746;\n}\n.art-video-player .hint--success.hint--right:before {\n border-right-color: #458746;\n}\n.art-video-player .hint--always:after,\n.art-video-player .hint--always:before {\n opacity: 1;\n visibility: visible;\n}\n.art-video-player .hint--always.hint--top:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top:after {\n -webkit-transform: translateX(-50%) translateY(-8px);\n -moz-transform: translateX(-50%) translateY(-8px);\n transform: translateX(-50%) translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-left:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-left:after {\n -webkit-transform: translateX(-100%) translateY(-8px);\n -moz-transform: translateX(-100%) translateY(-8px);\n transform: translateX(-100%) translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-right:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-right:after {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--bottom:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom:after {\n -webkit-transform: translateX(-50%) translateY(8px);\n -moz-transform: translateX(-50%) translateY(8px);\n transform: translateX(-50%) translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-left:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-left:after {\n -webkit-transform: translateX(-100%) translateY(8px);\n -moz-transform: translateX(-100%) translateY(8px);\n transform: translateX(-100%) translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-right:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-right:after {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--left:before {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--always.hint--left:after {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--always.hint--right:before {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--always.hint--right:after {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--rounded:after {\n border-radius: 4px;\n}\n.art-video-player .hint--no-animate:before,\n.art-video-player .hint--no-animate:after {\n -webkit-transition-duration: 0ms;\n -moz-transition-duration: 0ms;\n transition-duration: 0ms;\n}\n.art-video-player .hint--bounce:before,\n.art-video-player .hint--bounce:after {\n -webkit-transition: opacity 0.3s ease, visibility 0.3s ease, -webkit-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n -moz-transition: opacity 0.3s ease, visibility 0.3s ease, -moz-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n}\n.art-video-player .hint--no-shadow:before,\n.art-video-player .hint--no-shadow:after {\n text-shadow: initial;\n box-shadow: initial;\n}\n.art-video-player .hint--no-arrow:before {\n display: none;\n}\n.art-video-player.art-mobile {\n --art-bottom-gap: 10px;\n --art-control-height: 38px;\n --art-control-icon-scale: 1;\n --art-state-size: 60px;\n --art-settings-max-height: 180px;\n --art-selector-max-height: 180px;\n --art-indicator-scale: 1;\n --art-control-opacity: 1;\n}\n.art-video-player.art-mobile .art-controls-left {\n margin-left: calc(var(--art-padding) / -1);\n}\n.art-video-player.art-mobile .art-controls-right {\n margin-right: calc(var(--art-padding) / -1);\n}\n"; +const css = ".art-video-player {\n --art-theme: #f00;\n --art-font-color: #fff;\n --art-background-color: #000;\n --art-text-shadow-color: rgba(0, 0, 0, 0.5);\n --art-transition-duration: 0.2s;\n --art-padding: 10px;\n --art-border-radius: 3px;\n --art-progress-height: 6px;\n --art-progress-color: rgba(255, 255, 255, 0.25);\n --art-progress-top-gap: 10px;\n --art-hover-color: rgba(255, 255, 255, 0.25);\n --art-loaded-color: rgba(255, 255, 255, 0.25);\n --art-state-size: 80px;\n --art-state-opacity: 0.8;\n --art-bottom-height: 100px;\n --art-bottom-offset: 20px;\n --art-bottom-gap: 5px;\n --art-highlight-width: 8px;\n --art-highlight-color: rgba(255, 255, 255, 0.5);\n --art-control-height: 46px;\n --art-control-opacity: 0.75;\n --art-control-icon-size: 36px;\n --art-control-icon-scale: 1.1;\n --art-volume-height: 120px;\n --art-volume-handle-size: 14px;\n --art-lock-size: 36px;\n --art-indicator-scale: 0;\n --art-indicator-size: 16px;\n --art-fullscreen-web-index: 9999;\n --art-settings-icon-size: 24px;\n --art-settings-max-height: 300px;\n --art-selector-max-height: 300px;\n --art-contextmenus-min-width: 250px;\n --art-subtitle-font-size: 20px;\n --art-subtitle-gap: 5px;\n --art-subtitle-bottom: 15px;\n --art-subtitle-border: #000;\n --art-widget-background: rgba(0, 0, 0, 0.85);\n --art-tip-background: rgba(0, 0, 0, 0.7);\n --art-scrollbar-size: 4px;\n --art-scrollbar-background: rgba(255, 255, 255, 0.25);\n --art-scrollbar-background-hover: rgba(255, 255, 255, 0.5);\n --art-mini-progress-height: 2px;\n}\n.art-bg-cover {\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n}\n.art-bottom-gradient {\n background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0.4), transparent);\n background-repeat: repeat-x;\n background-position: center bottom;\n}\n.art-backdrop-filter {\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n backdrop-filter: saturate(180%) blur(20px);\n background-color: rgba(0, 0, 0, 0.75) !important;\n}\n.art-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.art-video-player {\n position: relative;\n margin: 0 auto;\n width: 100%;\n height: 100%;\n outline: 0;\n zoom: 1;\n padding: 0;\n text-align: left;\n direction: ltr;\n font-size: 14px;\n line-height: 1.3;\n user-select: none;\n box-sizing: border-box;\n color: var(--art-font-color);\n background-color: var(--art-background-color);\n text-shadow: 0 0 2px var(--art-text-shadow-color);\n font-family: PingFang SC, Helvetica Neue, Microsoft YaHei, Roboto, Arial, sans-serif;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n -ms-high-contrast-adjust: none;\n}\n.art-video-player *,\n.art-video-player *::before,\n.art-video-player *::after {\n box-sizing: border-box;\n}\n.art-video-player ::-webkit-scrollbar {\n width: var(--art-scrollbar-size);\n height: var(--art-scrollbar-size);\n}\n.art-video-player ::-webkit-scrollbar-thumb {\n background-color: var(--art-scrollbar-background);\n}\n.art-video-player ::-webkit-scrollbar-thumb:hover {\n background-color: var(--art-scrollbar-background-hover);\n}\n.art-video-player img {\n max-width: 100%;\n vertical-align: top;\n}\n.art-video-player svg {\n fill: var(--art-font-color);\n}\n.art-video-player a {\n color: var(--art-font-color);\n text-decoration: none;\n}\n.art-icon {\n line-height: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.art-video-player.art-backdrop .art-contextmenus,\n.art-video-player.art-backdrop .art-info,\n.art-video-player.art-backdrop .art-settings,\n.art-video-player.art-backdrop .art-layer-auto-playback,\n.art-video-player.art-backdrop .art-selector-list,\n.art-video-player.art-backdrop .art-volume-inner {\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n backdrop-filter: saturate(180%) blur(20px);\n background-color: rgba(0, 0, 0, 0.75) !important;\n}\n.art-video {\n position: absolute;\n inset: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n}\n.art-poster {\n position: absolute;\n inset: 0;\n z-index: 11;\n width: 100%;\n height: 100%;\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n pointer-events: none;\n}\n.art-video-player .art-subtitle {\n display: none;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n position: absolute;\n z-index: 20;\n width: 100%;\n padding: 0 5%;\n text-align: center;\n pointer-events: none;\n gap: var(--art-subtitle-gap);\n bottom: var(--art-subtitle-bottom);\n font-size: var(--art-subtitle-font-size);\n transition: bottom var(--art-transition-duration) ease;\n text-shadow: var(--art-subtitle-border) 1px 0 1px, var(--art-subtitle-border) 0 1px 1px, var(--art-subtitle-border) -1px 0 1px, var(--art-subtitle-border) 0 -1px 1px, var(--art-subtitle-border) 1px 1px 1px, var(--art-subtitle-border) -1px -1px 1px, var(--art-subtitle-border) 1px -1px 1px, var(--art-subtitle-border) -1px 1px 1px;\n}\n.art-video-player.art-subtitle-show .art-subtitle {\n display: flex;\n}\n.art-video-player.art-control-show .art-subtitle {\n bottom: calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom));\n}\n.art-danmuku {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: hidden;\n}\n.art-video-player .art-layers {\n position: absolute;\n inset: 0;\n z-index: 40;\n width: 100%;\n height: 100%;\n display: none;\n pointer-events: none;\n}\n.art-video-player .art-layers .art-layer {\n pointer-events: auto;\n}\n.art-video-player.art-layer-show .art-layers {\n display: flex;\n}\n.art-video-player .art-mask {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n inset: 0;\n z-index: 50;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-video-player .art-mask .art-state {\n display: flex;\n justify-content: center;\n align-items: center;\n opacity: 0;\n transform: scale(2);\n width: var(--art-state-size);\n height: var(--art-state-size);\n transition: all var(--art-transition-duration) ease;\n}\n.art-video-player.art-mask-show .art-state {\n pointer-events: auto;\n opacity: var(--art-state-opacity);\n transform: scale(1);\n}\n.art-video-player.art-loading-show .art-state {\n display: none;\n}\n.art-video-player .art-loading {\n display: none;\n justify-content: center;\n align-items: center;\n position: absolute;\n inset: 0;\n z-index: 70;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-video-player.art-loading-show .art-loading {\n display: flex;\n}\n.art-video-player.art-loading-show .art-mask {\n display: none;\n}\n.art-video-player .art-bottom {\n position: absolute;\n inset: 0;\n z-index: 60;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n padding: 0 var(--art-padding);\n transition: all var(--art-transition-duration) ease;\n background-size: 100% var(--art-bottom-height);\n background-image: linear-gradient(to top, #000, rgba(0, 0, 0, 0.4), transparent);\n background-repeat: repeat-x;\n background-position: center bottom;\n}\n.art-video-player .art-bottom .art-controls,\n.art-video-player .art-bottom .art-progress {\n transform: translateY(var(--art-bottom-offset));\n transition: transform var(--art-transition-duration) ease;\n}\n.art-video-player.art-control-show .art-bottom,\n.art-video-player.art-hover .art-bottom {\n opacity: 1;\n}\n.art-video-player.art-control-show .art-bottom .art-controls,\n.art-video-player.art-hover .art-bottom .art-controls,\n.art-video-player.art-control-show .art-bottom .art-progress,\n.art-video-player.art-hover .art-bottom .art-progress {\n transform: translateY(0);\n}\n.art-bottom .art-progress {\n position: relative;\n z-index: 0;\n cursor: pointer;\n pointer-events: auto;\n padding-top: var(--art-progress-top-gap);\n padding-bottom: var(--art-bottom-gap);\n}\n.art-bottom .art-progress .art-control-progress {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n height: var(--art-progress-height);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner {\n display: flex;\n align-items: center;\n position: relative;\n height: 50%;\n width: 100%;\n transition: height var(--art-transition-duration) ease;\n background-color: var(--art-progress-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-hover-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded {\n position: absolute;\n inset: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-loaded-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played {\n position: absolute;\n inset: 0;\n z-index: 20;\n width: 100%;\n height: 100%;\n width: 0%;\n background-color: var(--art-theme);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n right: auto;\n pointer-events: auto;\n width: var(--art-highlight-width) !important;\n transform: translateX(calc(var(--art-highlight-width) / -2));\n background-color: var(--art-highlight-color);\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n z-index: 40;\n left: 0;\n border-radius: 50%;\n width: var(--art-indicator-size);\n height: var(--art-indicator-size);\n transform: scale(var(--art-indicator-scale));\n margin-left: calc(var(--art-indicator-size) / -2);\n transition: transform var(--art-transition-duration) ease;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon {\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover {\n transform: scale(1.2) !important;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active {\n transform: scale(1) !important;\n}\n.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip {\n transform-origin: bottom center;\n transform: scale(0.5);\n opacity: 0;\n position: absolute;\n z-index: 50;\n top: -25px;\n left: 0;\n padding: 3px 5px;\n line-height: 1;\n font-size: 12px;\n border-radius: var(--art-border-radius);\n white-space: nowrap;\n background-color: var(--art-tip-background);\n transition: transform var(--art-transition-duration) ease, opacity var(--art-transition-duration) ease;\n}\n.art-bottom .art-progress .art-control-thumbnails {\n transform-origin: bottom center;\n transform: scale(0.5);\n opacity: 0;\n position: absolute;\n bottom: calc(var(--art-bottom-gap) + 10px);\n left: 0;\n border-radius: var(--art-border-radius);\n pointer-events: none;\n background-color: var(--art-widget-background);\n transition: transform var(--art-transition-duration) ease, opacity var(--art-transition-duration) ease;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 2px -1px rgba(0, 0, 0, 0.2);\n}\n.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner {\n height: 100%;\n}\n.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator {\n transform: scale(1);\n}\n.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,\n.art-progress-hover .art-bottom .art-progress .art-control-thumbnails {\n transform: scale(1);\n opacity: 1;\n}\n.art-video-player .art-controls {\n position: relative;\n z-index: 10;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n flex-shrink: 0;\n height: auto;\n min-height: var(--art-control-height);\n}\n.art-video-player .art-controls .art-controls-left,\n.art-video-player .art-controls .art-controls-right {\n display: flex;\n flex-wrap: wrap;\n max-width: 100%;\n min-height: var(--art-control-height);\n}\n.art-video-player .art-controls .art-controls-center {\n display: none;\n justify-content: center;\n align-items: center;\n flex: 1;\n height: 100%;\n padding: 0 10px;\n}\n.art-video-player .art-controls .art-controls-right {\n justify-content: flex-end;\n margin-left: auto;\n}\n.art-video-player .art-controls .art-control {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n max-width: 100%;\n cursor: pointer;\n white-space: nowrap;\n opacity: var(--art-control-opacity);\n min-height: var(--art-control-height);\n min-width: var(--art-control-height);\n transition: opacity var(--art-transition-duration) ease;\n}\n.art-video-player .art-controls .art-control .art-icon {\n height: var(--art-control-icon-size);\n width: var(--art-control-icon-size);\n transform: scale(var(--art-control-icon-scale));\n transition: transform var(--art-transition-duration) ease;\n}\n.art-video-player .art-controls .art-control .art-icon:active {\n transform: scale(calc(var(--art-control-icon-scale) * 0.8));\n}\n.art-video-player .art-controls .art-control:hover {\n opacity: 1;\n}\n.art-control-volume {\n position: relative;\n}\n.art-control-volume .art-volume-panel {\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n left: 0;\n right: 0;\n padding: 0 5px;\n font-size: 12px;\n text-align: center;\n cursor: default;\n opacity: 0;\n visibility: hidden;\n transform: translateY(10px);\n pointer-events: none;\n bottom: var(--art-control-height);\n width: var(--art-control-height);\n height: var(--art-volume-height);\n transition: opacity var(--art-transition-duration) ease, transform var(--art-transition-duration) ease;\n}\n.art-control-volume .art-volume-panel .art-volume-inner {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 10px;\n height: 100%;\n width: 100%;\n padding: 10px 0 12px;\n border-radius: var(--art-border-radius);\n background-color: var(--art-widget-background);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider {\n flex: 1;\n width: 100%;\n display: flex;\n cursor: pointer;\n position: relative;\n justify-content: center;\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle {\n position: relative;\n display: flex;\n justify-content: center;\n width: 2px;\n border-radius: var(--art-border-radius);\n overflow: hidden;\n background-color: rgba(255, 255, 255, 0.25);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded {\n position: absolute;\n inset: 0;\n z-index: 0;\n width: 100%;\n height: 100%;\n background-color: var(--art-theme);\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator {\n position: absolute;\n width: var(--art-volume-handle-size);\n height: var(--art-volume-handle-size);\n margin-top: calc(var(--art-volume-handle-size) / -2);\n flex-shrink: 0;\n transform: scale(1);\n border-radius: 100%;\n background-color: var(--art-theme);\n transition: transform var(--art-transition-duration) ease;\n}\n.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator {\n transform: scale(0.9);\n}\n.art-control-volume:hover .art-volume-panel,\n.art-control-volume:focus-within .art-volume-panel {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n pointer-events: auto;\n}\n.art-video-player .art-notice {\n display: none;\n position: absolute;\n inset: 0;\n z-index: 80;\n width: 100%;\n height: 100%;\n height: auto;\n bottom: auto;\n padding: var(--art-padding);\n pointer-events: none;\n}\n.art-video-player .art-notice .art-notice-inner {\n display: inline-flex;\n padding: 5px;\n line-height: 1;\n border-radius: var(--art-border-radius);\n background-color: var(--art-tip-background);\n}\n.art-video-player.art-notice-show .art-notice {\n display: flex;\n}\n.art-video-player .art-contextmenus {\n display: none;\n flex-direction: column;\n position: absolute;\n z-index: 120;\n padding: 5px 0;\n border-radius: var(--art-border-radius);\n font-size: 12px;\n background-color: var(--art-widget-background);\n min-width: var(--art-contextmenus-min-width);\n}\n.art-video-player .art-contextmenus .art-contextmenu {\n cursor: pointer;\n display: flex;\n padding: 10px 15px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-contextmenus .art-contextmenu span {\n padding: 0 8px;\n}\n.art-video-player .art-contextmenus .art-contextmenu span:hover,\n.art-video-player .art-contextmenus .art-contextmenu span.art-current {\n color: var(--art-theme);\n}\n.art-video-player .art-contextmenus .art-contextmenu:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-contextmenus .art-contextmenu:last-child {\n border-bottom: none;\n}\n.art-video-player.art-contextmenu-show .art-contextmenus {\n display: flex;\n}\n.art-video-player .art-settings {\n display: none;\n flex-direction: column;\n position: absolute;\n z-index: 90;\n left: auto;\n overflow-y: auto;\n overflow-x: hidden;\n border-radius: var(--art-border-radius);\n max-height: var(--art-settings-max-height);\n right: var(--art-padding);\n bottom: var(--art-controls-height, var(--art-control-height));\n transition: all var(--art-transition-duration) ease;\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-settings .art-setting-panel {\n display: none;\n flex-direction: column;\n}\n.art-video-player .art-settings .art-setting-panel.art-current {\n display: flex;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 5px;\n padding: 0 5px;\n cursor: pointer;\n overflow: hidden;\n transition: background-color var(--art-transition-duration) ease;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current {\n color: var(--art-theme);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check {\n visibility: hidden;\n height: 15px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check {\n visibility: visible;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n gap: 5px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n height: var(--art-settings-icon-size);\n width: var(--art-settings-icon-size);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-width: 0;\n max-width: 55%;\n gap: 5px;\n font-size: 12px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(255, 255, 255, 0.5);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-width: 32px;\n height: 24px;\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range {\n height: 3px;\n width: 80px;\n outline: none;\n appearance: none;\n background-color: rgba(255, 255, 255, 0.2);\n}\n.art-video-player .art-settings .art-setting-panel .art-setting-item-back {\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.art-video-player.art-setting-show .art-settings {\n display: flex;\n}\n.art-video-player .art-info {\n display: none;\n position: absolute;\n left: var(--art-padding);\n top: var(--art-padding);\n z-index: 100;\n padding: 10px;\n font-size: 12px;\n border-radius: var(--art-border-radius);\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-info .art-info-panel {\n display: flex;\n flex-direction: column;\n gap: 5px;\n}\n.art-video-player .art-info .art-info-panel .art-info-item {\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.art-video-player .art-info .art-info-panel .art-info-item .art-info-title {\n width: 100px;\n text-align: right;\n}\n.art-video-player .art-info .art-info-panel .art-info-item .art-info-content {\n width: 250px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n user-select: all;\n}\n.art-video-player .art-info .art-info-close {\n position: absolute;\n top: 5px;\n right: 5px;\n cursor: pointer;\n}\n.art-video-player.art-info-show .art-info {\n display: flex;\n}\n.art-hide-cursor * {\n cursor: none !important;\n}\n.art-video-player[data-aspect-ratio] {\n overflow: hidden;\n}\n.art-video-player[data-aspect-ratio] .art-video {\n object-fit: fill;\n box-sizing: content-box;\n}\n.art-fullscreen {\n --art-progress-height: 8px;\n --art-indicator-size: 20px;\n --art-control-height: 60px;\n --art-control-icon-scale: 1.3;\n}\n.art-fullscreen-web {\n --art-progress-height: 8px;\n --art-indicator-size: 20px;\n --art-control-height: 60px;\n --art-control-icon-scale: 1.3;\n position: fixed;\n inset: 0;\n z-index: var(--art-fullscreen-web-index);\n width: 100%;\n height: 100%;\n}\n.art-mini-popup {\n position: fixed;\n z-index: 9999;\n width: 320px;\n height: 180px;\n max-width: 100vw;\n max-height: 100vh;\n background: #000;\n border-radius: var(--art-border-radius);\n cursor: move;\n user-select: none;\n overflow: hidden;\n transition: opacity 0.2s ease;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);\n}\n.art-mini-popup svg {\n fill: #fff;\n}\n.art-mini-popup .art-video {\n pointer-events: none;\n}\n.art-mini-popup .art-mini-close {\n position: absolute;\n z-index: 20;\n right: 10px;\n top: 10px;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n.art-mini-popup .art-mini-state {\n position: absolute;\n inset: 0;\n z-index: 30;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.2s ease;\n background-color: rgba(0, 0, 0, 0.25);\n}\n.art-mini-popup .art-mini-state .art-icon {\n opacity: 0.75;\n cursor: pointer;\n transform: scale(3);\n pointer-events: auto;\n transition: transform 0.2s ease;\n}\n.art-mini-popup .art-mini-state .art-icon:active {\n transform: scale(2.5);\n}\n.art-mini-popup.art-mini-dragging {\n opacity: 0.9;\n}\n.art-mini-popup:hover .art-mini-close,\n.art-mini-popup:focus-within .art-mini-close,\n.art-mini-popup:hover .art-mini-state,\n.art-mini-popup:focus-within .art-mini-state {\n opacity: 1;\n}\n.art-mini-popup [role='button']:focus-visible {\n outline: 2px solid #fff;\n outline-offset: -2px;\n}\n.art-video-player[data-flip='horizontal'] .art-video {\n transform: scaleX(-1);\n}\n.art-video-player[data-flip='vertical'] .art-video {\n transform: scaleY(-1);\n}\n.art-video-player .art-layer-lock {\n display: none;\n justify-content: center;\n align-items: center;\n position: absolute;\n top: 50%;\n border-radius: 50%;\n transform: translateY(-50%);\n height: var(--art-lock-size);\n width: var(--art-lock-size);\n left: var(--art-padding);\n background-color: var(--art-tip-background);\n}\n.art-video-player .art-layer-auto-playback {\n display: none;\n gap: 10px;\n align-items: center;\n position: absolute;\n border-radius: var(--art-border-radius);\n padding: 10px;\n line-height: 1;\n left: var(--art-padding);\n bottom: calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);\n background-color: var(--art-widget-background);\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-close {\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-close svg {\n width: 15px;\n height: 15px;\n fill: var(--art-theme);\n}\n.art-video-player .art-layer-auto-playback .art-auto-playback-jump {\n color: var(--art-theme);\n cursor: pointer;\n}\n.art-video-player.art-lock .art-layer-lock {\n display: flex;\n}\n.art-video-player.art-lock:not(.art-control-show) .art-layer-lock {\n opacity: 0;\n pointer-events: none;\n}\n.art-video-player.art-lock:not(.art-control-show) .art-layer-lock:focus-within {\n opacity: 1;\n pointer-events: auto;\n}\n.art-video-player.art-lock .art-subtitle {\n bottom: var(--art-subtitle-bottom) !important;\n}\n.art-video-player.art-mini-progress-bar .art-bottom,\n.art-video-player.art-lock .art-bottom {\n opacity: 1;\n padding: 0;\n background-image: none;\n}\n.art-video-player.art-mini-progress-bar .art-bottom .art-controls,\n.art-video-player.art-lock .art-bottom .art-controls,\n.art-video-player.art-mini-progress-bar .art-bottom .art-progress,\n.art-video-player.art-lock .art-bottom .art-progress {\n transform: translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4));\n}\n.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,\n.art-video-player.art-lock .art-bottom .art-progress-indicator {\n display: none !important;\n}\n.art-video-player.art-control-show .art-layer-lock {\n display: flex;\n}\n.art-control-selector {\n position: relative;\n display: flex;\n justify-content: center;\n}\n.art-control-selector .art-selector-list {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n position: absolute;\n border-radius: var(--art-border-radius);\n overflow-y: auto;\n overflow-x: hidden;\n opacity: 0;\n visibility: hidden;\n transform: translateY(10px);\n pointer-events: none;\n bottom: var(--art-control-height);\n max-height: var(--art-selector-max-height);\n background-color: var(--art-widget-background);\n transition: opacity var(--art-transition-duration) ease, transform var(--art-transition-duration) ease;\n}\n.art-control-selector .art-selector-list .art-selector-item {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n padding: 10px 15px;\n flex-shrink: 0;\n line-height: 1;\n}\n.art-control-selector .art-selector-list .art-selector-item:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n.art-control-selector .art-selector-list .art-selector-item:hover,\n.art-control-selector .art-selector-list .art-selector-item.art-current {\n color: var(--art-theme);\n}\n.art-control-selector:hover:not(.art-selector-dismissed) .art-selector-list,\n.art-control-selector.art-selector-open .art-selector-list {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n pointer-events: auto;\n}\n.art-video-player {\n /*! Hint.css - v2.7.0 - 2021-10-01\n * https://kushagra.dev/lab/hint/\n * Copyright (c) 2021 Kushagra Gour */\n /*-------------------------------------*\\\n HINT.css - A CSS tooltip library\n \\*-------------------------------------*/\n /**\n * HINT.css is a tooltip library made in pure CSS.\n *\n * Source: https://github.com/chinchang/hint.css\n * Demo: http://kushagragour.in/lab/hint/\n *\n */\n /**\n * source: hint-core.scss\n *\n * Defines the basic styling for the tooltip.\n * Each tooltip is made of 2 parts:\n * 1) body (:after)\n * 2) arrow (:before)\n *\n * Classes added:\n * 1) hint\n */\n /**\n * source: hint-position.scss\n *\n * Defines the positoning logic for the tooltips.\n *\n * Classes added:\n * 1) hint--top\n * 2) hint--bottom\n * 3) hint--left\n * 4) hint--right\n */\n /**\n * set default color for tooltip arrows\n */\n /**\n * top tooltip\n */\n /**\n * bottom tooltip\n */\n /**\n * right tooltip\n */\n /**\n * left tooltip\n */\n /**\n * top-left tooltip\n */\n /**\n * top-right tooltip\n */\n /**\n * bottom-left tooltip\n */\n /**\n * bottom-right tooltip\n */\n /**\n * source: hint-sizes.scss\n *\n * Defines width restricted tooltips that can span\n * across multiple lines.\n *\n * Classes added:\n * 1) hint--small\n * 2) hint--medium\n * 3) hint--large\n *\n */\n /**\n * source: hint-theme.scss\n *\n * Defines basic theme for tooltips.\n *\n */\n /**\n * source: hint-color-types.scss\n *\n * Contains tooltips of various types based on color differences.\n *\n * Classes added:\n * 1) hint--error\n * 2) hint--warning\n * 3) hint--info\n * 4) hint--success\n *\n */\n /**\n * Error\n */\n /**\n * Warning\n */\n /**\n * Info\n */\n /**\n * Success\n */\n /**\n * source: hint-always.scss\n *\n * Defines a persisted tooltip which shows always.\n *\n * Classes added:\n * 1) hint--always\n *\n */\n /**\n * source: hint-rounded.scss\n *\n * Defines rounded corner tooltips.\n *\n * Classes added:\n * 1) hint--rounded\n *\n */\n /**\n * source: hint-effects.scss\n *\n * Defines various transition effects for the tooltips.\n *\n * Classes added:\n * 1) hint--no-animate\n * 2) hint--bounce\n *\n */\n}\n.art-video-player [class*='hint--'] {\n position: relative;\n display: inline-block;\n font-style: normal;\n /**\n * tooltip arrow\n */\n /**\n * tooltip body\n */\n}\n.art-video-player [class*='hint--']:before,\n.art-video-player [class*='hint--']:after {\n position: absolute;\n -webkit-transform: translate3d(0, 0, 0);\n -moz-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n visibility: hidden;\n opacity: 0;\n z-index: 1000000;\n pointer-events: none;\n -webkit-transition: 0.3s ease;\n -moz-transition: 0.3s ease;\n transition: 0.3s ease;\n -webkit-transition-delay: 0ms;\n -moz-transition-delay: 0ms;\n transition-delay: 0ms;\n}\n.art-video-player [class*='hint--']:hover:before,\n.art-video-player [class*='hint--']:hover:after {\n visibility: visible;\n opacity: 1;\n}\n.art-video-player [class*='hint--']:hover:before,\n.art-video-player [class*='hint--']:hover:after {\n -webkit-transition-delay: 100ms;\n -moz-transition-delay: 100ms;\n transition-delay: 100ms;\n}\n.art-video-player [class*='hint--']:before {\n content: '';\n position: absolute;\n background: transparent;\n border: 6px solid transparent;\n z-index: 1000001;\n}\n.art-video-player [class*='hint--']:after {\n background: #000000;\n color: white;\n padding: 8px 10px;\n font-size: 12px;\n font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n line-height: 12px;\n white-space: nowrap;\n}\n.art-video-player [class*='hint--'][aria-label]:after {\n content: attr(aria-label);\n}\n.art-video-player [class*='hint--'][data-hint]:after {\n content: attr(data-hint);\n}\n.art-video-player [aria-label='']:before,\n.art-video-player [aria-label='']:after,\n.art-video-player [data-hint='']:before,\n.art-video-player [data-hint='']:after {\n display: none !important;\n}\n.art-video-player .hint--top-left:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--top-right:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--top:before {\n border-top-color: #000000;\n}\n.art-video-player .hint--bottom-left:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--bottom-right:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--bottom:before {\n border-bottom-color: #000000;\n}\n.art-video-player .hint--left:before {\n border-left-color: #000000;\n}\n.art-video-player .hint--right:before {\n border-right-color: #000000;\n}\n.art-video-player .hint--top:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top:before,\n.art-video-player .hint--top:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top:after {\n -webkit-transform: translateX(-50%);\n -moz-transform: translateX(-50%);\n transform: translateX(-50%);\n}\n.art-video-player .hint--top:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top:hover:after {\n -webkit-transform: translateX(-50%) translateY(-8px);\n -moz-transform: translateX(-50%) translateY(-8px);\n transform: translateX(-50%) translateY(-8px);\n}\n.art-video-player .hint--bottom:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom:before,\n.art-video-player .hint--bottom:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom:after {\n -webkit-transform: translateX(-50%);\n -moz-transform: translateX(-50%);\n transform: translateX(-50%);\n}\n.art-video-player .hint--bottom:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom:hover:after {\n -webkit-transform: translateX(-50%) translateY(8px);\n -moz-transform: translateX(-50%) translateY(8px);\n transform: translateX(-50%) translateY(8px);\n}\n.art-video-player .hint--right:before {\n margin-left: -11px;\n margin-bottom: -6px;\n}\n.art-video-player .hint--right:after {\n margin-bottom: -14px;\n}\n.art-video-player .hint--right:before,\n.art-video-player .hint--right:after {\n left: 100%;\n bottom: 50%;\n}\n.art-video-player .hint--right:hover:before {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--right:hover:after {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--left:before {\n margin-right: -11px;\n margin-bottom: -6px;\n}\n.art-video-player .hint--left:after {\n margin-bottom: -14px;\n}\n.art-video-player .hint--left:before,\n.art-video-player .hint--left:after {\n right: 100%;\n bottom: 50%;\n}\n.art-video-player .hint--left:hover:before {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--left:hover:after {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--top-left:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top-left:before,\n.art-video-player .hint--top-left:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top-left:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top-left:after {\n -webkit-transform: translateX(-100%);\n -moz-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n.art-video-player .hint--top-left:after {\n margin-left: 12px;\n}\n.art-video-player .hint--top-left:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top-left:hover:after {\n -webkit-transform: translateX(-100%) translateY(-8px);\n -moz-transform: translateX(-100%) translateY(-8px);\n transform: translateX(-100%) translateY(-8px);\n}\n.art-video-player .hint--top-right:before {\n margin-bottom: -11px;\n}\n.art-video-player .hint--top-right:before,\n.art-video-player .hint--top-right:after {\n bottom: 100%;\n left: 50%;\n}\n.art-video-player .hint--top-right:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--top-right:after {\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n transform: translateX(0);\n}\n.art-video-player .hint--top-right:after {\n margin-left: -12px;\n}\n.art-video-player .hint--top-right:hover:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--top-right:hover:after {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--bottom-left:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom-left:before,\n.art-video-player .hint--bottom-left:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom-left:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom-left:after {\n -webkit-transform: translateX(-100%);\n -moz-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n.art-video-player .hint--bottom-left:after {\n margin-left: 12px;\n}\n.art-video-player .hint--bottom-left:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom-left:hover:after {\n -webkit-transform: translateX(-100%) translateY(8px);\n -moz-transform: translateX(-100%) translateY(8px);\n transform: translateX(-100%) translateY(8px);\n}\n.art-video-player .hint--bottom-right:before {\n margin-top: -11px;\n}\n.art-video-player .hint--bottom-right:before,\n.art-video-player .hint--bottom-right:after {\n top: 100%;\n left: 50%;\n}\n.art-video-player .hint--bottom-right:before {\n left: calc(50% - 6px);\n}\n.art-video-player .hint--bottom-right:after {\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n transform: translateX(0);\n}\n.art-video-player .hint--bottom-right:after {\n margin-left: -12px;\n}\n.art-video-player .hint--bottom-right:hover:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--bottom-right:hover:after {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--small:after,\n.art-video-player .hint--medium:after,\n.art-video-player .hint--large:after {\n white-space: normal;\n line-height: 1.4em;\n word-wrap: break-word;\n}\n.art-video-player .hint--small:after {\n width: 80px;\n}\n.art-video-player .hint--medium:after {\n width: 150px;\n}\n.art-video-player .hint--large:after {\n width: 300px;\n}\n.art-video-player [class*='hint--'] {\n /**\n * tooltip body\n */\n}\n.art-video-player [class*='hint--']:after {\n text-shadow: 0 -1px 0px black;\n box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);\n}\n.art-video-player .hint--error:after {\n background-color: #b34e4d;\n text-shadow: 0 -1px 0px #592726;\n}\n.art-video-player .hint--error.hint--top-left:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--top-right:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--top:before {\n border-top-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom-left:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom-right:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--bottom:before {\n border-bottom-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--left:before {\n border-left-color: #b34e4d;\n}\n.art-video-player .hint--error.hint--right:before {\n border-right-color: #b34e4d;\n}\n.art-video-player .hint--warning:after {\n background-color: #c09854;\n text-shadow: 0 -1px 0px #6c5328;\n}\n.art-video-player .hint--warning.hint--top-left:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--top-right:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--top:before {\n border-top-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom-left:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom-right:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--bottom:before {\n border-bottom-color: #c09854;\n}\n.art-video-player .hint--warning.hint--left:before {\n border-left-color: #c09854;\n}\n.art-video-player .hint--warning.hint--right:before {\n border-right-color: #c09854;\n}\n.art-video-player .hint--info:after {\n background-color: #3986ac;\n text-shadow: 0 -1px 0px #1a3c4d;\n}\n.art-video-player .hint--info.hint--top-left:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--top-right:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--top:before {\n border-top-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom-left:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom-right:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--bottom:before {\n border-bottom-color: #3986ac;\n}\n.art-video-player .hint--info.hint--left:before {\n border-left-color: #3986ac;\n}\n.art-video-player .hint--info.hint--right:before {\n border-right-color: #3986ac;\n}\n.art-video-player .hint--success:after {\n background-color: #458746;\n text-shadow: 0 -1px 0px #1a321a;\n}\n.art-video-player .hint--success.hint--top-left:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--top-right:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--top:before {\n border-top-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom-left:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom-right:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--bottom:before {\n border-bottom-color: #458746;\n}\n.art-video-player .hint--success.hint--left:before {\n border-left-color: #458746;\n}\n.art-video-player .hint--success.hint--right:before {\n border-right-color: #458746;\n}\n.art-video-player .hint--always:after,\n.art-video-player .hint--always:before {\n opacity: 1;\n visibility: visible;\n}\n.art-video-player .hint--always.hint--top:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top:after {\n -webkit-transform: translateX(-50%) translateY(-8px);\n -moz-transform: translateX(-50%) translateY(-8px);\n transform: translateX(-50%) translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-left:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-left:after {\n -webkit-transform: translateX(-100%) translateY(-8px);\n -moz-transform: translateX(-100%) translateY(-8px);\n transform: translateX(-100%) translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-right:before {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--top-right:after {\n -webkit-transform: translateY(-8px);\n -moz-transform: translateY(-8px);\n transform: translateY(-8px);\n}\n.art-video-player .hint--always.hint--bottom:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom:after {\n -webkit-transform: translateX(-50%) translateY(8px);\n -moz-transform: translateX(-50%) translateY(8px);\n transform: translateX(-50%) translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-left:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-left:after {\n -webkit-transform: translateX(-100%) translateY(8px);\n -moz-transform: translateX(-100%) translateY(8px);\n transform: translateX(-100%) translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-right:before {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--bottom-right:after {\n -webkit-transform: translateY(8px);\n -moz-transform: translateY(8px);\n transform: translateY(8px);\n}\n.art-video-player .hint--always.hint--left:before {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--always.hint--left:after {\n -webkit-transform: translateX(-8px);\n -moz-transform: translateX(-8px);\n transform: translateX(-8px);\n}\n.art-video-player .hint--always.hint--right:before {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--always.hint--right:after {\n -webkit-transform: translateX(8px);\n -moz-transform: translateX(8px);\n transform: translateX(8px);\n}\n.art-video-player .hint--rounded:after {\n border-radius: 4px;\n}\n.art-video-player .hint--no-animate:before,\n.art-video-player .hint--no-animate:after {\n -webkit-transition-duration: 0ms;\n -moz-transition-duration: 0ms;\n transition-duration: 0ms;\n}\n.art-video-player .hint--bounce:before,\n.art-video-player .hint--bounce:after {\n -webkit-transition: opacity 0.3s ease, visibility 0.3s ease, -webkit-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n -moz-transition: opacity 0.3s ease, visibility 0.3s ease, -moz-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);\n}\n.art-video-player .hint--no-shadow:before,\n.art-video-player .hint--no-shadow:after {\n text-shadow: initial;\n box-shadow: initial;\n}\n.art-video-player .hint--no-arrow:before {\n display: none;\n}\n.art-video-player.art-mobile {\n --art-bottom-gap: 10px;\n --art-control-height: 38px;\n --art-control-icon-scale: 1;\n --art-state-size: 60px;\n --art-settings-max-height: 180px;\n --art-selector-max-height: 180px;\n --art-indicator-scale: 1;\n --art-control-opacity: 1;\n}\n.art-video-player.art-mobile .art-controls-left {\n margin-left: calc(var(--art-padding) / -1);\n}\n.art-video-player.art-mobile .art-controls-right {\n margin-right: calc(var(--art-padding) / -1);\n}\n.art-video-player [tabindex]:focus-visible,\n.art-video-player input:focus-visible,\n.art-video-player button:focus-visible,\n.art-video-player a:focus-visible {\n outline: 2px solid currentColor;\n outline-offset: -2px;\n}\n.art-video-player.art-keyboard-focus :focus {\n outline: 2px solid currentColor;\n outline-offset: -2px;\n}\n.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom {\n opacity: 1;\n}\n.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-controls,\n.art-video-player.art-keyboard-focus:not(.art-lock) .art-bottom .art-progress {\n transform: translateY(0);\n}\n"; function parseSubtitle(buffer, option) { const text = new TextDecoder(option.encoding).decode(buffer); switch (option.type || getExt(option.url)) { diff --git a/packages/artplayer/dist/artplayer.mts b/packages/artplayer/dist/artplayer.mts new file mode 100644 index 000000000..7400ac73a --- /dev/null +++ b/packages/artplayer/dist/artplayer.mts @@ -0,0 +1,2 @@ +export { default } from './artplayer.cjs' +export type { Config, Emitter, Events, I18n, Icons, Option, OptionInput, PlaybackControls, Player, PluginFactory, Plugins, Setting, SettingOption, Subtitle, SubtitleUpdateEvents, Template, Utils } from './artplayer.js' diff --git a/packages/artplayer/dist/artplayer.ts b/packages/artplayer/dist/artplayer.ts new file mode 100644 index 000000000..df439aaa2 --- /dev/null +++ b/packages/artplayer/dist/artplayer.ts @@ -0,0 +1,216 @@ +import type { Component } from './component' +import type { Config } from './config' +import type { Emitter } from './emitter' +import type { Events, SubtitleUpdateEvents } from './events' +import type { I18n } from './i18n' +import type { Icons } from './icons' +import type { Option, OptionInput } from './option' +import type { PlaybackControls } from './playback' +import type { Player } from './player' +import type { PluginFactory, Plugins } from './plugin' +import type { Setting, SettingOption } from './setting' +import type { Subtitle } from './subtitle' +import type { Template } from './template' +import type { Utils } from './utils' + +export type { + Config, + Emitter, + Events, + I18n, + Icons, + Option, + OptionInput, + PlaybackControls, + Player, + PluginFactory, + Plugins, + Setting, + SettingOption, + Subtitle, + SubtitleUpdateEvents, + Template, + Utils, +} + +declare class Artplayer extends Player { + constructor(option: Option, readyCallback?: (this: Artplayer, art: Artplayer) => unknown) + constructor(option: OptionInput, readyCallback?: (this: Artplayer, art: Artplayer) => unknown) + + static readonly instances: Artplayer[] + static readonly version: string + static readonly env: 'development' | 'production' + static readonly build: string + static readonly config: Config + static readonly utils: Utils + static readonly scheme: Record + static readonly Emitter: new >(...args: unknown[]) => Emitter + static readonly validator: (option: T, scheme: object) => T + static readonly kindOf: (item: unknown) => string + static readonly html: Artplayer['template']['html'] + static readonly option: Option + + static STYLE: string + static DEBUG: boolean + static CONTEXTMENU: boolean + static NOTICE_TIME: number + static SETTING_WIDTH: number + static SETTING_ITEM_WIDTH: number + static SETTING_ITEM_HEIGHT: number + static RESIZE_TIME: number + static SCROLL_TIME: number + static SCROLL_GAP: number + static AUTO_PLAYBACK_MAX: number + static AUTO_PLAYBACK_MIN: number + static AUTO_PLAYBACK_TIMEOUT: number + static RECONNECT_TIME_MAX: number + static RECONNECT_SLEEP_TIME: number + static CONTROL_HIDE_TIME: number + static DBCLICK_TIME: number + static DBCLICK_FULLSCREEN: boolean + static MOBILE_DBCLICK_PLAY: boolean + static MOBILE_CLICK_PLAY: boolean + static AUTO_ORIENTATION_TIME: number + static INFO_LOOP_TIME: number + static FAST_FORWARD_VALUE: number + static FAST_FORWARD_TIME: number + static TOUCH_MOVE_RATIO: number + static VOLUME_STEP: number + static SEEK_STEP: number + static PLAYBACK_RATE: number[] + static ASPECT_RATIO: string[] + static FLIP: string[] + static FULLSCREEN_WEB_IN_BODY: boolean + static LOG_VERSION: boolean + static USE_RAF: boolean + static REMOVE_SRC_WHEN_DESTROY: boolean + + readonly id: number + readonly option: Option + readonly isLock: boolean + readonly isReady: boolean + readonly isFocus: boolean + readonly isInput: boolean + readonly isRotate: boolean + readonly isDestroy: boolean + + flv?: unknown + m3u8?: unknown + hls?: unknown + ts?: unknown + mpd?: unknown + torrent?: unknown + + on(name: T, fn: (...args: Events[T]) => unknown, ctx?: object): this + on(name: T, fn: (...args: SubtitleUpdateEvents[T]) => unknown, ctx?: object): this + on(name: string, fn: (...args: unknown[]) => unknown, ctx?: object): this + + once(name: T, fn: (...args: Events[T]) => unknown, ctx?: object): this + once(name: T, fn: (...args: SubtitleUpdateEvents[T]) => unknown, ctx?: object): this + once(name: string, fn: (...args: unknown[]) => unknown, ctx?: object): this + + emit(name: T, ...args: Events[T]): this + emit(name: T, ...args: SubtitleUpdateEvents[T]): this + emit(name: string, ...args: unknown[]): this + + off(name: T, callback?: (...args: Events[T]) => unknown): this + off(name: T, callback?: (...args: SubtitleUpdateEvents[T]) => unknown): this + off(name: string, callback?: (...args: unknown[]) => unknown): this + + query: Artplayer['template']['query'] + proxy: Artplayer['events']['proxy'] + video: Artplayer['template']['$video'] + + e: { [K in keyof Events]?: { fn: (...args: Events[K]) => unknown, ctx: unknown }[] } + + destroy(removeHtml?: boolean): void + reset(): void + + readonly template: { + get html(): string + query: (selector: string) => T | null + } & Template + + readonly events: { + proxy: { + (target: EventTarget, eventName: string, handler: (event: Event) => void, options?: boolean | AddEventListenerOptions): () => void + (target: EventTarget, eventName: string[], handler: (event: Event) => void, options?: boolean | AddEventListenerOptions): Array<() => void> + } + hover: (element: HTMLElement, mouseenter?: (event: Event) => any, mouseleave?: (event: Event) => any) => void + remove: (destroyEvent: () => void) => void + destroy: () => void + bindGlobalEvents: (source?: { window?: Window, document?: Document }) => void + } + + readonly storage: { + name: string + settings: Record + get: { + (key: string): unknown + (): Record + } + set: (key: string, value: unknown) => void + del: (key: string) => void + clear: () => void + } + + readonly icons: Icons + + readonly i18n: { + languages: I18n + language: Partial> + init: () => void + get: (key: string) => string + update: (language: Partial) => void + } + + readonly notice: { + timer: number | null + get show(): string | Error | false | '' + set show(msg: string | Error | false | '') + destroy: () => void + } + + readonly layers: Record & Component + readonly controls: Record & Component + readonly contextmenu: Record & Component + + readonly subtitle: { + get url(): string + set url(url: string) + get textTrack(): TextTrack | undefined + get activeCues(): VTTCue[] + get cues(): VTTCue[] + style: (name: string | Partial, value?: string) => void + switch: (url: string, option?: Subtitle) => Promise + init: (subtitle: Subtitle) => Promise + } & Component + + readonly info: Component + readonly loading: Component + + readonly hotkey: { + keys: Record any)[]> + add: (key: string, callback: (this: Artplayer, event: KeyboardEvent) => any) => Artplayer['hotkey'] + remove: (key: string, callback: (event: KeyboardEvent) => any) => Artplayer['hotkey'] + } + + readonly mask: Component + + readonly setting: { + option: SettingOption[] + updateStyle: (width?: number) => void + /** Legacy return signature; a missing runtime entry is null. */ + find: (name: string) => SettingOption | undefined + /** Legacy return signature; runtime returns the formatted input item. */ + add: (setting: Setting) => Artplayer['setting'] + /** Legacy return signature; runtime returns the updated or added item. */ + update: (settings: Setting) => Artplayer['setting'] + /** Legacy return signature; runtime returns undefined. */ + remove: (name: string) => Artplayer['setting'] + } & Component + + readonly plugins: Plugins +} + +export default Artplayer diff --git a/packages/artplayer/dist/component.ts b/packages/artplayer/dist/component.ts new file mode 100644 index 000000000..7fdf4213d --- /dev/null +++ b/packages/artplayer/dist/component.ts @@ -0,0 +1,143 @@ +import type Artplayer from './artplayer' + +/** Input accepted by the existing HTML renderer, including numeric content. */ +export interface ComponentInput extends Omit { + html?: string | HTMLElement | number +} + +export interface Selector { + /** + * Whether the default is selected + */ + default?: boolean + + /** + * Html string of selector + */ + html: string | HTMLElement + + /** + * Value of selector item + */ + value?: string | number + + /** + * Allow custom properties + */ + [key: string]: any +} + +export interface Component { + /** + * Component self-increasing id + */ + readonly id: number + + /** + * Component parent name + */ + readonly name: string | undefined + + /** + * Component parent element + */ + readonly $parent: HTMLElement | undefined + + /** + * Whether to show component parent + */ + get show(): boolean + + /** + * Whether to show component parent + */ + set show(state: boolean) + + /** + * Toggle the component parent + */ + toggle: () => void + + /** + * Dynamic add a component + */ + add: { + (option: ComponentOption | ((art: Artplayer) => ComponentOption)): HTMLElement | undefined + (option: ComponentInput | ((art: Artplayer) => ComponentInput)): HTMLElement | undefined + } + + /** + * Dynamic remove a component by name + */ + remove: (name: string) => void + + /** + * Dynamic update a component + */ + update: { + (option: ComponentOption): HTMLElement | undefined + (option: ComponentInput): HTMLElement | undefined + } +} + +export interface ComponentOption { + /** + * Html string or html element of component + */ + html?: string | HTMLElement + + /** + * Whether to disable component + */ + disable?: boolean + + /** + * Unique name for component + */ + name?: string + + /** + * Component sort index + */ + index?: number + + /** + * Component style object + */ + style?: Partial + + /** + * Component click event + */ + click?: (this: Artplayer, component: Component, event: Event) => void + + /** + * When the component was mounted + */ + mounted?: (this: Artplayer, element: HTMLElement) => void + + /** + * When the component was before unmount + */ + beforeUnmount?: (this: Artplayer, element: HTMLElement) => void + + /** + * Component tooltip, use in controls + */ + tooltip?: string + + /** + * Component position, use in controls + */ + position?: 'top' | 'left' | 'right' | (string & Record) + + /** + * Custom selector list, use in controls + */ + selector?: Selector[] + + /** + * When selector item click, use in controls + */ + onSelect?: (this: Artplayer, selector: Selector, element: HTMLElement, event: Event) => void +} diff --git a/packages/artplayer/dist/config.ts b/packages/artplayer/dist/config.ts new file mode 100644 index 000000000..11c753b4e --- /dev/null +++ b/packages/artplayer/dist/config.ts @@ -0,0 +1,81 @@ +export interface Config { + readonly properties: readonly [ + 'audioTracks', + 'autoplay', + 'buffered', + 'controller', + 'controls', + 'crossOrigin', + 'currentSrc', + 'currentTime', + 'defaultMuted', + 'defaultPlaybackRate', + 'duration', + 'ended', + 'error', + 'loop', + 'mediaGroup', + 'muted', + 'networkState', + 'paused', + 'playbackRate', + 'played', + 'preload', + 'readyState', + 'seekable', + 'seeking', + 'src', + 'startDate', + 'textTracks', + 'videoTracks', + 'volume', + ] + readonly methods: readonly ['addTextTrack', 'canPlayType', 'load', 'play', 'pause'] + readonly events: readonly [ + 'abort', + 'canplay', + 'canplaythrough', + 'durationchange', + 'emptied', + 'ended', + 'error', + 'loadeddata', + 'loadedmetadata', + 'loadstart', + 'pause', + 'play', + 'playing', + 'progress', + 'ratechange', + 'seeked', + 'seeking', + 'stalled', + 'suspend', + 'timeupdate', + 'volumechange', + 'waiting', + ] + readonly prototypes: readonly [ + 'width', + 'height', + 'videoWidth', + 'videoHeight', + 'poster', + 'webkitDecodedFrameCount', + 'webkitDroppedFrameCount', + 'playsInline', + 'webkitSupportsFullscreen', + 'webkitDisplayingFullscreen', + 'onenterpictureinpicture', + 'onleavepictureinpicture', + 'disablePictureInPicture', + 'cancelVideoFrameCallback', + 'requestVideoFrameCallback', + 'getVideoPlaybackQuality', + 'requestPictureInPicture', + 'webkitEnterFullScreen', + 'webkitEnterFullscreen', + 'webkitExitFullScreen', + 'webkitExitFullscreen', + ] +} diff --git a/packages/artplayer/dist/cssVar.ts b/packages/artplayer/dist/cssVar.ts new file mode 100644 index 000000000..e9384c07f --- /dev/null +++ b/packages/artplayer/dist/cssVar.ts @@ -0,0 +1,45 @@ +export interface CssVar { + '--art-theme': string + '--art-font-color': string + '--art-background-color': string + '--art-text-shadow-color': string + '--art-transition-duration': string + '--art-padding': string + '--art-border-radius': string + '--art-progress-height': string + '--art-progress-color': string + '--art-progress-top-gap': string + '--art-hover-color': string + '--art-loaded-color': string + '--art-state-size': string + '--art-state-opacity': number + '--art-bottom-height': string + '--art-bottom-offset': string + '--art-bottom-gap': string + '--art-highlight-width': string + '--art-highlight-color': string + '--art-control-height': string + '--art-control-opacity': number + '--art-control-icon-size': string + '--art-control-icon-scale': number + '--art-volume-height': string + '--art-volume-handle-size': string + '--art-lock-size': string + '--art-indicator-scale': number + '--art-indicator-size': string + '--art-fullscreen-web-index': 9999 + '--art-settings-icon-size': string + '--art-settings-max-height': string + '--art-selector-max-height': string + '--art-contextmenus-min-width': string + '--art-subtitle-font-size': string + '--art-subtitle-gap': string + '--art-subtitle-bottom': string + '--art-subtitle-border': string + '--art-widget-background': string + '--art-tip-background': string + '--art-scrollbar-size': string + '--art-scrollbar-background': string + '--art-scrollbar-background-hover': string + '--art-mini-progress-height': string +} diff --git a/packages/artplayer/dist/emitter.ts b/packages/artplayer/dist/emitter.ts new file mode 100644 index 000000000..f9bb749c1 --- /dev/null +++ b/packages/artplayer/dist/emitter.ts @@ -0,0 +1,8 @@ +/** The event bus exposed by Artplayer.Emitter; no new runtime export. */ +export interface Emitter> { + e?: { [Name in keyof Events]?: { fn: (...args: [...Events[Name]]) => unknown, ctx: unknown }[] } + on: (name: Name, fn: (this: Context, ...args: [...Events[Name]]) => unknown, ctx?: Context) => this + once: (name: Name, fn: (this: Context, ...args: [...Events[Name]]) => unknown, ctx?: Context) => this + emit: (name: Name, ...args: [...Events[Name]]) => this + off: (name: Name, fn?: (...args: [...Events[Name]]) => unknown) => this +} diff --git a/packages/artplayer/dist/events.ts b/packages/artplayer/dist/events.ts new file mode 100644 index 000000000..624bbd55a --- /dev/null +++ b/packages/artplayer/dist/events.ts @@ -0,0 +1,106 @@ +import type { AspectRatio, Flip } from './player' +import type { Subtitle } from './subtitle' + +export type Bar = 'loaded' | 'played' | 'hover' + +/** Actual built-in subtitle update payloads; legacy Events keeps its scalar types. */ +export interface SubtitleUpdateEvents { + subtitleBeforeUpdate: [cues: VTTCue[]] + subtitleAfterUpdate: [cues: VTTCue[]] +} + +export interface Events { + 'document:click': [event: Event] + 'document:mouseup': [event: Event] + 'document:keydown': [event: Event] + 'document:touchend': [event: Event] + 'document:touchcancel': [event: Event] + 'document:touchmove': [event: Event] + 'document:mousemove': [event: Event] + 'document:pointerup': [event: Event] + 'document:contextmenu': [event: Event] + 'document:pointermove': [event: Event] + 'document:visibilitychange': [event: Event] + 'document:webkitfullscreenchange': [event: Event] + + 'window:resize': [event: Event] + 'window:scroll': [event: Event] + 'window:orientationchange': [event: Event] + + 'video:abort': [event: Event] + 'video:canplay': [event: Event] + 'video:canplaythrough': [event: Event] + 'video:complete': [event: Event] + 'video:durationchange': [event: Event] + 'video:emptied': [event: Event] + 'video:encrypted': [event: Event] + 'video:ended': [event: Event] + 'video:error': [error: Error] + 'video:loadeddata': [event: Event] + 'video:loadedmetadata': [event: Event] + 'video:loadstart': [event: Event] + 'video:pause': [event: Event] + 'video:play': [event: Event] + 'video:playing': [event: Event] + 'video:progress': [event: Event] + 'video:ratechange': [event: Event] + 'video:seeked': [event: Event] + 'video:seeking': [event: Event] + 'video:stalled': [event: Event] + 'video:suspend': [event: Event] + 'video:timeupdate': [event: Event] + 'video:volumechange': [event: Event] + 'video:waiting': [event: Event] + + 'info': [state: boolean] + 'layer': [state: boolean] + 'loading': [state: boolean] + 'mask': [state: boolean] + 'subtitle': [state: boolean] + 'contextmenu': [state: boolean] + 'control': [state: boolean] + 'setting': [state: boolean] + 'hotkey': [event: KeyboardEvent] + + 'destroy': [] + + 'subtitleOffset': [offset: number] + /** Legacy contextual type; annotate listeners with VTTCue[] for the runtime payload. */ + 'subtitleBeforeUpdate': [cue: VTTCue] + /** Legacy contextual type; annotate listeners with VTTCue[] for the runtime payload. */ + 'subtitleAfterUpdate': [cue: VTTCue] + 'subtitleLoad': [cues: VTTCue[], option: Subtitle] + + 'focus': [event: Event] + 'blur': [event: Event] + 'dblclick': [event: Event] + 'click': [event: Event] + 'hover': [state: boolean, event: Event] + 'mousemove': [event: Event] + + 'resize': [] + 'view': [state: boolean] + 'lock': [state: boolean] + 'aspectRatio': [aspectRatio: AspectRatio] + 'autoHeight': [height: number] + 'autoSize': [size: { width: number, height: number }] + 'ready': [] + 'airplay': [] + 'raf': [] + + 'error': [error: Error, reconnectTime: number] + 'flip': [flip: Flip] + 'fullscreen': [state: boolean] + 'fullscreenError': [event: Event] + 'fullscreenWeb': [state: boolean] + 'mini': [state: boolean] + 'pause': [] + 'pip': [state: boolean] + 'play': [] + 'screenshot': [dataUri: string] + 'seek': [currentTime: number, time: number] + 'restart': [url: string] + 'muted': [state: boolean] + 'setBar': [type: Bar, percentage: number, event?: Event | undefined] + 'keydown': [event: KeyboardEvent] +} diff --git a/packages/artplayer/dist/i18n.ts b/packages/artplayer/dist/i18n.ts new file mode 100644 index 000000000..214c5dec2 --- /dev/null +++ b/packages/artplayer/dist/i18n.ts @@ -0,0 +1,61 @@ +type I18nKeys + = | 'en' + | 'zh-cn' + | 'zh-tw' + | 'pl' + | 'cs' + | 'es' + | 'fa' + | 'fr' + | 'id' + | 'ru' + | 'tr' + | 'ar' + | 'vi' + | (string & Record) + +interface I18nValue { + 'Context Menu'?: string + 'Lock'?: string + 'Video Info': string + 'Close': string + 'Video Load Failed': string + 'Volume': string + 'Progress'?: string + 'Back'?: string + 'Settings'?: string + 'Play': string + 'Pause': string + 'Rate': string + 'Mute': string + 'Video Flip': string + 'Horizontal': string + 'Vertical': string + 'Reconnect': string + 'Show Setting': string + 'Hide Setting': string + 'Screenshot': string + 'Play Speed': string + 'Aspect Ratio': string + 'Default': string + 'Normal': string + 'Open': string + 'Switch Video': string + 'Switch Subtitle': string + 'Fullscreen': string + 'Exit Fullscreen': string + 'Web Fullscreen': string + 'Exit Web Fullscreen': string + 'Mini Player': string + 'PIP Mode': string + 'Exit PIP Mode': string + 'PIP Not Supported': string + 'Fullscreen Not Supported': string + 'Subtitle Offset': string + 'Last Seen': string + 'Jump Play': string + 'AirPlay': string + 'AirPlay Not Available': string +} + +export type I18n = Partial>> diff --git a/packages/artplayer/dist/i18n/ar.js b/packages/artplayer/dist/i18n/ar.js index 56879d868..6bb90b887 100644 --- a/packages/artplayer/dist/i18n/ar.js +++ b/packages/artplayer/dist/i18n/ar.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nAr=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Video Info":"معلومات الفيديو",Close:"إغلاق","Video Load Failed":"فشل تحميل الفيديو",Volume:"الصوت",Play:"تشغيل",Pause:"إيقاف مؤقت",Rate:"السرعة",Mute:"كتم الصوت","Video Flip":"تدوير الفيديو",Horizontal:"أفقي",Vertical:"عمودي",Reconnect:"إعادة الاتصال","Show Setting":"إظهار الإعدادات","Hide Setting":"إخفاء الإعدادات",Screenshot:"لقطة شاشة","Play Speed":"سرعة التشغيل","Aspect Ratio":"نسبة العرض إلى الارتفاع",Default:"افتراضي",Normal:"عادي",Open:"فتح","Switch Video":"تبديل الفيديو","Switch Subtitle":"تبديل الترجمة",Fullscreen:"وضع ملء الشاشة","Exit Fullscreen":"الخروج من وضع ملء الشاشة","Web Fullscreen":"وضع ملء الشاشة في المتصفح","Exit Web Fullscreen":"الخروج من وضع ملء الشاشة في المتصفح","Mini Player":"مشغل صغير","PIP Mode":"الوضع العائم","Exit PIP Mode":"الخروج من الوضع العائم","PIP Not Supported":"الوضع العائم غير مدعوم","Fullscreen Not Supported":"وضع ملء الشاشة غير مدعوم","Subtitle Offset":"إزاحة الترجمة","Last Seen":"آخر مشاهدة","Jump Play":"التشغيل القافز",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay غير متاح"};return t("artplayer-i18n-ar",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nAr=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"قائمة السياق",Lock:"قفل",Back:"رجوع",Settings:"الإعدادات",Progress:"تقدم التشغيل","Video Info":"معلومات الفيديو",Close:"إغلاق","Video Load Failed":"فشل تحميل الفيديو",Volume:"الصوت",Play:"تشغيل",Pause:"إيقاف مؤقت",Rate:"السرعة",Mute:"كتم الصوت","Video Flip":"تدوير الفيديو",Horizontal:"أفقي",Vertical:"عمودي",Reconnect:"إعادة الاتصال","Show Setting":"إظهار الإعدادات","Hide Setting":"إخفاء الإعدادات",Screenshot:"لقطة شاشة","Play Speed":"سرعة التشغيل","Aspect Ratio":"نسبة العرض إلى الارتفاع",Default:"افتراضي",Normal:"عادي",Open:"فتح","Switch Video":"تبديل الفيديو","Switch Subtitle":"تبديل الترجمة",Fullscreen:"وضع ملء الشاشة","Exit Fullscreen":"الخروج من وضع ملء الشاشة","Web Fullscreen":"وضع ملء الشاشة في المتصفح","Exit Web Fullscreen":"الخروج من وضع ملء الشاشة في المتصفح","Mini Player":"مشغل صغير","PIP Mode":"الوضع العائم","Exit PIP Mode":"الخروج من الوضع العائم","PIP Not Supported":"الوضع العائم غير مدعوم","Fullscreen Not Supported":"وضع ملء الشاشة غير مدعوم","Subtitle Offset":"إزاحة الترجمة","Last Seen":"آخر مشاهدة","Jump Play":"التشغيل القافز",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay غير متاح"};return t("artplayer-i18n-ar",e),e})); diff --git a/packages/artplayer/dist/i18n/ar.mjs b/packages/artplayer/dist/i18n/ar.mjs index 0715c4758..e65ed2219 100644 --- a/packages/artplayer/dist/i18n/ar.mjs +++ b/packages/artplayer/dist/i18n/ar.mjs @@ -5,6 +5,11 @@ function i(e, t) { } } const o = { + "Context Menu": "قائمة السياق", + Lock: "قفل", + Back: "رجوع", + Settings: "الإعدادات", + Progress: "تقدم التشغيل", "Video Info": "معلومات الفيديو", Close: "إغلاق", "Video Load Failed": "فشل تحميل الفيديو", diff --git a/packages/artplayer/dist/i18n/cs.js b/packages/artplayer/dist/i18n/cs.js index e6f1c7098..990d835aa 100644 --- a/packages/artplayer/dist/i18n/cs.js +++ b/packages/artplayer/dist/i18n/cs.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nCs=e())})(this,(function(){"use strict";function t(o,i){if(typeof window<"u"){const n=window;n[o]=i}}const e={"Video Info":"Info o videu",Close:"Zavřít","Video Load Failed":"Nahrání videa selhalo",Volume:"Hlasitost",Play:"Přehrát",Pause:"Pozastavit",Rate:"Hodnocení",Mute:"Ztlumit","Video Flip":"Otočit video",Horizontal:"Horizontálně",Vertical:"Vertikálně",Reconnect:"Opětovné připojení","Show Setting":"Zobrazit nastavení","Hide Setting":"Skrýt nastavení",Screenshot:"Snímek obrazovky","Play Speed":"Rychlost přehrávání","Aspect Ratio":"Poměr stran",Default:"Výchozí",Normal:"Normální",Open:"Otevřít","Switch Video":"Přepnout video","Switch Subtitle":"Přepnout titulky",Fullscreen:"Celá obrazovka","Exit Fullscreen":"Opustit režim celé obrazovky","Web Fullscreen":"Celá stránka","Exit Web Fullscreen":"Zavřít režim celé stránky","Mini Player":"Mini přehrávač","PIP Mode":"Režim PIP","Exit PIP Mode":"Opustit režim PIP","PIP Not Supported":"Režim PIP není podporován","Fullscreen Not Supported":"Režim celé obrazovky není podporován","Subtitle Offset":"Posun titulků","Last Seen":"Naposledy viděn","Jump Play":"Hra na skok",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay není k dispozici"};return t("artplayer-i18n-cs",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nCs=e())})(this,(function(){"use strict";function t(o,n){if(typeof window<"u"){const i=window;i[o]=n}}const e={"Context Menu":"Kontextová nabídka",Lock:"Zamknout",Back:"Zpět",Settings:"Nastavení",Progress:"Průběh přehrávání","Video Info":"Info o videu",Close:"Zavřít","Video Load Failed":"Nahrání videa selhalo",Volume:"Hlasitost",Play:"Přehrát",Pause:"Pozastavit",Rate:"Hodnocení",Mute:"Ztlumit","Video Flip":"Otočit video",Horizontal:"Horizontálně",Vertical:"Vertikálně",Reconnect:"Opětovné připojení","Show Setting":"Zobrazit nastavení","Hide Setting":"Skrýt nastavení",Screenshot:"Snímek obrazovky","Play Speed":"Rychlost přehrávání","Aspect Ratio":"Poměr stran",Default:"Výchozí",Normal:"Normální",Open:"Otevřít","Switch Video":"Přepnout video","Switch Subtitle":"Přepnout titulky",Fullscreen:"Celá obrazovka","Exit Fullscreen":"Opustit režim celé obrazovky","Web Fullscreen":"Celá stránka","Exit Web Fullscreen":"Zavřít režim celé stránky","Mini Player":"Mini přehrávač","PIP Mode":"Režim PIP","Exit PIP Mode":"Opustit režim PIP","PIP Not Supported":"Režim PIP není podporován","Fullscreen Not Supported":"Režim celé obrazovky není podporován","Subtitle Offset":"Posun titulků","Last Seen":"Naposledy viděn","Jump Play":"Hra na skok",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay není k dispozici"};return t("artplayer-i18n-cs",e),e})); diff --git a/packages/artplayer/dist/i18n/cs.mjs b/packages/artplayer/dist/i18n/cs.mjs index d91cd5a05..8ad580eb6 100644 --- a/packages/artplayer/dist/i18n/cs.mjs +++ b/packages/artplayer/dist/i18n/cs.mjs @@ -1,10 +1,15 @@ -function i(e, t) { +function n(e, t) { if (typeof window < "u") { const o = window; o[e] = t; } } -const n = { +const i = { + "Context Menu": "Kontextová nabídka", + Lock: "Zamknout", + Back: "Zpět", + Settings: "Nastavení", + Progress: "Průběh přehrávání", "Video Info": "Info o videu", Close: "Zavřít", "Video Load Failed": "Nahrání videa selhalo", @@ -42,7 +47,7 @@ const n = { AirPlay: "AirPlay", "AirPlay Not Available": "AirPlay není k dispozici" }; -i("artplayer-i18n-cs", n); +n("artplayer-i18n-cs", i); export { - n as default + i as default }; diff --git a/packages/artplayer/dist/i18n/es.js b/packages/artplayer/dist/i18n/es.js index 9727a28e9..ce18e92d5 100644 --- a/packages/artplayer/dist/i18n/es.js +++ b/packages/artplayer/dist/i18n/es.js @@ -1 +1 @@ -(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nEs=e())})(this,(function(){"use strict";function a(o,t){if(typeof window<"u"){const l=window;l[o]=t}}const e={"Video Info":"Información del video",Close:"Cerrar","Video Load Failed":"Falló carga de video",Volume:"Volumen",Play:"Reproduciendo",Pause:"Pausa",Rate:"Velocidad",Mute:"Silencio","Video Flip":"Rotar video",Horizontal:"Horizontal",Vertical:"Vertical",Reconnect:"Reconectando","Show Setting":"Mostrar ajustes","Hide Setting":"Ocultar ajustes",Screenshot:"Captura de Pantalla","Play Speed":"Velocidad de reproducción","Aspect Ratio":"Relación de aspecto",Default:"Por defecto",Normal:"Normal",Open:"Abrir","Switch Video":"Cambiar video","Switch Subtitle":"Cambiar subtítulo",Fullscreen:"Pantalla completa","Exit Fullscreen":"Salir de Pantalla completa","Web Fullscreen":"Pantalla completa Web","Exit Web Fullscreen":"Salir de Pantalla completa","Mini Player":"Mini reproductor","PIP Mode":"Modo PiP","Exit PIP Mode":"Cerrar modo PiP","PIP Not Supported":"Modo PiP no compatible","Fullscreen Not Supported":"Pantalla completa no soportada","Subtitle Offset":"Ajuste subtítulo","Last Seen":"Visto última vez","Jump Play":"Saltar",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay no disponible"};return a("artplayer-i18n-es",e),e})); +(function(o,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self,o.artplayerI18nEs=e())})(this,(function(){"use strict";function o(a,t){if(typeof window<"u"){const i=window;i[a]=t}}const e={"Context Menu":"Menú contextual",Lock:"Bloquear",Back:"Volver",Settings:"Configuración",Progress:"Progreso de reproducción","Video Info":"Información del video",Close:"Cerrar","Video Load Failed":"Falló carga de video",Volume:"Volumen",Play:"Reproduciendo",Pause:"Pausa",Rate:"Velocidad",Mute:"Silencio","Video Flip":"Rotar video",Horizontal:"Horizontal",Vertical:"Vertical",Reconnect:"Reconectando","Show Setting":"Mostrar ajustes","Hide Setting":"Ocultar ajustes",Screenshot:"Captura de Pantalla","Play Speed":"Velocidad de reproducción","Aspect Ratio":"Relación de aspecto",Default:"Por defecto",Normal:"Normal",Open:"Abrir","Switch Video":"Cambiar video","Switch Subtitle":"Cambiar subtítulo",Fullscreen:"Pantalla completa","Exit Fullscreen":"Salir de Pantalla completa","Web Fullscreen":"Pantalla completa Web","Exit Web Fullscreen":"Salir de Pantalla completa","Mini Player":"Mini reproductor","PIP Mode":"Modo PiP","Exit PIP Mode":"Cerrar modo PiP","PIP Not Supported":"Modo PiP no compatible","Fullscreen Not Supported":"Pantalla completa no soportada","Subtitle Offset":"Ajuste subtítulo","Last Seen":"Visto última vez","Jump Play":"Saltar",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay no disponible"};return o("artplayer-i18n-es",e),e})); diff --git a/packages/artplayer/dist/i18n/es.mjs b/packages/artplayer/dist/i18n/es.mjs index 7e2c07bdf..e068ccbd7 100644 --- a/packages/artplayer/dist/i18n/es.mjs +++ b/packages/artplayer/dist/i18n/es.mjs @@ -5,6 +5,11 @@ function l(e, a) { } } const t = { + "Context Menu": "Menú contextual", + Lock: "Bloquear", + Back: "Volver", + Settings: "Configuración", + Progress: "Progreso de reproducción", "Video Info": "Información del video", Close: "Cerrar", "Video Load Failed": "Falló carga de video", diff --git a/packages/artplayer/dist/i18n/fa.js b/packages/artplayer/dist/i18n/fa.js index cd956a510..b28834810 100644 --- a/packages/artplayer/dist/i18n/fa.js +++ b/packages/artplayer/dist/i18n/fa.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nFa=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Video Info":"اطلاعات ویدیو",Close:"بستن","Video Load Failed":"بارگذاری ناموفق",Play:"پخش",Volume:"میزان صدا",Pause:"توقف",Rate:"نرخ",Mute:"سکوت","Video Flip":"چرخش تصویر",Horizontal:"افقی",Vertical:"عمودی",Reconnect:"اتصال مجدد","Show Setting":"تنظیمات","Hide Setting":"بستن تنظیمات",Screenshot:"عکس از صفحه","Play Speed":"سرعت پخش","Aspect Ratio":"نسبت تصویر",Default:"حالت پیشفرض",Normal:" حالت عادی",Open:"بازکردن","Switch Video":"تغییر ویدیو","Switch Subtitle":"نغییر زیرنویس",Fullscreen:"تمام صفحه","Exit Fullscreen":"کوچک کردن","Web Fullscreen":"حالت تئاتر","Exit Web Fullscreen":"خروج از حالت تئاتر","Mini Player":"حالت پخش کوچک","PIP Mode":" مینی پلیر","Exit PIP Mode":"خروج از مینی پلیر","PIP Not Supported":"عدم پشتیبانی از مینی پلیر","Fullscreen Not Supported":"عدم پشتیبانی از حالت تمام صفحه","Subtitle Offset":"افست زیرنویس","Last Seen":"آخرین بازدید","Jump Play":"جامپ پلی",AirPlay:"ایر پلی","AirPlay Not Available":"عدم پشتیبانی از ایرپلی"};return t("artplayer-i18n-fa",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nFa=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"منوی زمینه",Lock:"قفل",Back:"بازگشت",Settings:"تنظیمات",Progress:"پیشرفت پخش","Video Info":"اطلاعات ویدیو",Close:"بستن","Video Load Failed":"بارگذاری ناموفق",Play:"پخش",Volume:"میزان صدا",Pause:"توقف",Rate:"نرخ",Mute:"سکوت","Video Flip":"چرخش تصویر",Horizontal:"افقی",Vertical:"عمودی",Reconnect:"اتصال مجدد","Show Setting":"تنظیمات","Hide Setting":"بستن تنظیمات",Screenshot:"عکس از صفحه","Play Speed":"سرعت پخش","Aspect Ratio":"نسبت تصویر",Default:"حالت پیشفرض",Normal:" حالت عادی",Open:"بازکردن","Switch Video":"تغییر ویدیو","Switch Subtitle":"نغییر زیرنویس",Fullscreen:"تمام صفحه","Exit Fullscreen":"کوچک کردن","Web Fullscreen":"حالت تئاتر","Exit Web Fullscreen":"خروج از حالت تئاتر","Mini Player":"حالت پخش کوچک","PIP Mode":" مینی پلیر","Exit PIP Mode":"خروج از مینی پلیر","PIP Not Supported":"عدم پشتیبانی از مینی پلیر","Fullscreen Not Supported":"عدم پشتیبانی از حالت تمام صفحه","Subtitle Offset":"افست زیرنویس","Last Seen":"آخرین بازدید","Jump Play":"جامپ پلی",AirPlay:"ایر پلی","AirPlay Not Available":"عدم پشتیبانی از ایرپلی"};return t("artplayer-i18n-fa",e),e})); diff --git a/packages/artplayer/dist/i18n/fa.mjs b/packages/artplayer/dist/i18n/fa.mjs index dd354c207..d445c8f14 100644 --- a/packages/artplayer/dist/i18n/fa.mjs +++ b/packages/artplayer/dist/i18n/fa.mjs @@ -1,10 +1,15 @@ -function i(e, t) { +function o(e, t) { if (typeof window < "u") { const l = window; l[e] = t; } } -const o = { +const i = { + "Context Menu": "منوی زمینه", + Lock: "قفل", + Back: "بازگشت", + Settings: "تنظیمات", + Progress: "پیشرفت پخش", "Video Info": "اطلاعات ویدیو", Close: "بستن", "Video Load Failed": "بارگذاری ناموفق", @@ -42,7 +47,7 @@ const o = { AirPlay: "ایر پلی", "AirPlay Not Available": "عدم پشتیبانی از ایرپلی" }; -i("artplayer-i18n-fa", o); +o("artplayer-i18n-fa", i); export { - o as default + i as default }; diff --git a/packages/artplayer/dist/i18n/fr.js b/packages/artplayer/dist/i18n/fr.js index 23e16561b..2c491252c 100644 --- a/packages/artplayer/dist/i18n/fr.js +++ b/packages/artplayer/dist/i18n/fr.js @@ -1 +1 @@ -(function(i,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(i=typeof globalThis<"u"?globalThis:i||self,i.artplayerI18nFr=e())})(this,(function(){"use strict";function i(t,n){if(typeof window<"u"){const o=window;o[t]=n}}const e={"Video Info":"Informations de la vidéo",Close:"Fermer","Video Load Failed":"Téléchargement de la vidéo échoué",Volume:"Volume",Play:"Lire",Pause:"Pause",Rate:"Vitesse",Mute:"Muet","Video Flip":"Rotation de la vidéo",Horizontal:"Horizontal",Vertical:"Vertical",Reconnect:"Reconnexion","Show Setting":"Afficher les paramètres","Hide Setting":"Cacher les paramètres",Screenshot:"Capture d'écran","Play Speed":"Vitesse de lecture","Aspect Ratio":"Rapport d'aspect",Default:"Défaut",Normal:"Normal",Open:"Ouvrir","Switch Video":"Basculer la vidéo","Switch Subtitle":"Basculer le sous-titre",Fullscreen:"Plein écran","Exit Fullscreen":"Quitter le plein écran","Web Fullscreen":"Plein écran Web","Exit Web Fullscreen":"Quitter le plein écran Web","Mini Player":"Mini lecteur","PIP Mode":"Mode PiP","Exit PIP Mode":"Fermer le mode PiP","PIP Not Supported":"Mode PiP non supporté","Fullscreen Not Supported":"Plein écran non supporté","Subtitle Offset":"Réglage des sous-titres","Last Seen":"Dernière position","Jump Play":"Continuer",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay non disponible"};return i("artplayer-i18n-fr",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nFr=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"Menu contextuel",Lock:"Verrouiller",Back:"Retour",Settings:"Paramètres",Progress:"Progression de lecture","Video Info":"Informations de la vidéo",Close:"Fermer","Video Load Failed":"Téléchargement de la vidéo échoué",Volume:"Volume",Play:"Lire",Pause:"Pause",Rate:"Vitesse",Mute:"Muet","Video Flip":"Rotation de la vidéo",Horizontal:"Horizontal",Vertical:"Vertical",Reconnect:"Reconnexion","Show Setting":"Afficher les paramètres","Hide Setting":"Cacher les paramètres",Screenshot:"Capture d'écran","Play Speed":"Vitesse de lecture","Aspect Ratio":"Rapport d'aspect",Default:"Défaut",Normal:"Normal",Open:"Ouvrir","Switch Video":"Basculer la vidéo","Switch Subtitle":"Basculer le sous-titre",Fullscreen:"Plein écran","Exit Fullscreen":"Quitter le plein écran","Web Fullscreen":"Plein écran Web","Exit Web Fullscreen":"Quitter le plein écran Web","Mini Player":"Mini lecteur","PIP Mode":"Mode PiP","Exit PIP Mode":"Fermer le mode PiP","PIP Not Supported":"Mode PiP non supporté","Fullscreen Not Supported":"Plein écran non supporté","Subtitle Offset":"Réglage des sous-titres","Last Seen":"Dernière position","Jump Play":"Continuer",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay non disponible"};return t("artplayer-i18n-fr",e),e})); diff --git a/packages/artplayer/dist/i18n/fr.mjs b/packages/artplayer/dist/i18n/fr.mjs index 29c134a75..45fe9a61f 100644 --- a/packages/artplayer/dist/i18n/fr.mjs +++ b/packages/artplayer/dist/i18n/fr.mjs @@ -1,10 +1,15 @@ -function l(e, i) { +function i(e, t) { if (typeof window < "u") { - const t = window; - t[e] = i; + const r = window; + r[e] = t; } } const o = { + "Context Menu": "Menu contextuel", + Lock: "Verrouiller", + Back: "Retour", + Settings: "Paramètres", + Progress: "Progression de lecture", "Video Info": "Informations de la vidéo", Close: "Fermer", "Video Load Failed": "Téléchargement de la vidéo échoué", @@ -42,7 +47,7 @@ const o = { AirPlay: "AirPlay", "AirPlay Not Available": "AirPlay non disponible" }; -l("artplayer-i18n-fr", o); +i("artplayer-i18n-fr", o); export { o as default }; diff --git a/packages/artplayer/dist/i18n/id.js b/packages/artplayer/dist/i18n/id.js index 96bdc9828..83ffa844a 100644 --- a/packages/artplayer/dist/i18n/id.js +++ b/packages/artplayer/dist/i18n/id.js @@ -1 +1 @@ -(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nId=e())})(this,(function(){"use strict";function a(i,t){if(typeof window<"u"){const n=window;n[i]=t}}const e={"Video Info":"Informasi Video",Close:"Tutup","Video Load Failed":"Gagal Memuat Video",Volume:"Volume",Play:"Putar",Pause:"Jeda",Rate:"Kecepatan",Mute:"Senyap","Video Flip":"Memutar Video",Horizontal:"Horizontal",Vertical:"Vertikal",Reconnect:"Menyambung Kembali","Show Setting":"Tampilkan Pengaturan","Hide Setting":"Sembunyikan Pengaturan",Screenshot:"Tangkapan Layar","Play Speed":"Kecepatan Putar","Aspect Ratio":"Rasio Aspek",Default:"Default",Normal:"Normal",Open:"Buka","Switch Video":"Ganti Video","Switch Subtitle":"Ganti Subtitle",Fullscreen:"Layar Penuh","Exit Fullscreen":"Keluar dari Layar Penuh","Web Fullscreen":"Layar Penuh Web","Exit Web Fullscreen":"Keluar dari Layar Penuh Web","Mini Player":"Pemutar Mini","PIP Mode":"Mode PIP","Exit PIP Mode":"Keluar dari Mode PIP","PIP Not Supported":"PIP Tidak Didukung","Fullscreen Not Supported":"Layar Penuh Tidak Didukung","Subtitle Offset":"Pergeseran Subtitle","Last Seen":"Terakhir Dilihat","Jump Play":"Lompat Putar",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay Tidak Tersedia"};return a("artplayer-i18n-id",e),e})); +(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nId=e())})(this,(function(){"use strict";function a(i,n){if(typeof window<"u"){const t=window;t[i]=n}}const e={"Context Menu":"Menu konteks",Lock:"Kunci",Back:"Kembali",Settings:"Pengaturan",Progress:"Progres pemutaran","Video Info":"Informasi Video",Close:"Tutup","Video Load Failed":"Gagal Memuat Video",Volume:"Volume",Play:"Putar",Pause:"Jeda",Rate:"Kecepatan",Mute:"Senyap","Video Flip":"Memutar Video",Horizontal:"Horizontal",Vertical:"Vertikal",Reconnect:"Menyambung Kembali","Show Setting":"Tampilkan Pengaturan","Hide Setting":"Sembunyikan Pengaturan",Screenshot:"Tangkapan Layar","Play Speed":"Kecepatan Putar","Aspect Ratio":"Rasio Aspek",Default:"Default",Normal:"Normal",Open:"Buka","Switch Video":"Ganti Video","Switch Subtitle":"Ganti Subtitle",Fullscreen:"Layar Penuh","Exit Fullscreen":"Keluar dari Layar Penuh","Web Fullscreen":"Layar Penuh Web","Exit Web Fullscreen":"Keluar dari Layar Penuh Web","Mini Player":"Pemutar Mini","PIP Mode":"Mode PIP","Exit PIP Mode":"Keluar dari Mode PIP","PIP Not Supported":"PIP Tidak Didukung","Fullscreen Not Supported":"Layar Penuh Tidak Didukung","Subtitle Offset":"Pergeseran Subtitle","Last Seen":"Terakhir Dilihat","Jump Play":"Lompat Putar",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay Tidak Tersedia"};return a("artplayer-i18n-id",e),e})); diff --git a/packages/artplayer/dist/i18n/id.mjs b/packages/artplayer/dist/i18n/id.mjs index 9f09df5a8..734cf6378 100644 --- a/packages/artplayer/dist/i18n/id.mjs +++ b/packages/artplayer/dist/i18n/id.mjs @@ -5,6 +5,11 @@ function t(e, a) { } } const n = { + "Context Menu": "Menu konteks", + Lock: "Kunci", + Back: "Kembali", + Settings: "Pengaturan", + Progress: "Progres pemutaran", "Video Info": "Informasi Video", Close: "Tutup", "Video Load Failed": "Gagal Memuat Video", diff --git a/packages/artplayer/dist/i18n/pl.js b/packages/artplayer/dist/i18n/pl.js index dd8775b71..b2a81a4d5 100644 --- a/packages/artplayer/dist/i18n/pl.js +++ b/packages/artplayer/dist/i18n/pl.js @@ -1 +1 @@ -(function(i,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(i=typeof globalThis<"u"?globalThis:i||self,i.artplayerI18nPl=e())})(this,(function(){"use strict";function i(n,o){if(typeof window<"u"){const t=window;t[n]=o}}const e={"Video Info":"Informacje o wideo",Close:"Zamknij","Video Load Failed":"Błąd ładowania wideo",Volume:"Głośność",Play:"Odtwórz",Pause:"Wstrzymaj",Rate:"Oceń",Mute:"Wycisz","Video Flip":"Rotacja wideo",Horizontal:"Pozioma",Vertical:"Pionowa",Reconnect:"Połącz ponownie","Show Setting":"Pokaż ustawienia","Hide Setting":"Ukryj ustawienia",Screenshot:"Zrzut ekranu","Play Speed":"Prędkość odtwarzania","Aspect Ratio":"Współczynnik proporcji",Default:"Domyślny",Normal:"Normalny",Open:"Otwórz","Switch Video":"Przełącz wideo","Switch Subtitle":"Przełącz napisy",Fullscreen:"Pełny ekran","Exit Fullscreen":"Zamknij pełny ekran","Web Fullscreen":"Tryb pełnej strony","Exit Web Fullscreen":"Zamknij tryb pełnej strony","Mini Player":"Miniodtwarzacz","PIP Mode":"Tryb PiP","Exit PIP Mode":"Zamknij tryb PiP","PIP Not Supported":"Tryb PiP nieobsługiwany","Fullscreen Not Supported":"Pełny ekran nieobsługiwany","Subtitle Offset":"Przesunięcie napisów","Last Seen":"Ostatnio widziany","Jump Play":"Skocz do gry",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay nie jest dostępny"};return i("artplayer-i18n-pl",e),e})); +(function(n,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(n=typeof globalThis<"u"?globalThis:n||self,n.artplayerI18nPl=e())})(this,(function(){"use strict";function n(i,o){if(typeof window<"u"){const t=window;t[i]=o}}const e={"Context Menu":"Menu kontekstowe",Lock:"Zablokuj",Back:"Wstecz",Settings:"Ustawienia",Progress:"Postęp odtwarzania","Video Info":"Informacje o wideo",Close:"Zamknij","Video Load Failed":"Błąd ładowania wideo",Volume:"Głośność",Play:"Odtwórz",Pause:"Wstrzymaj",Rate:"Oceń",Mute:"Wycisz","Video Flip":"Rotacja wideo",Horizontal:"Pozioma",Vertical:"Pionowa",Reconnect:"Połącz ponownie","Show Setting":"Pokaż ustawienia","Hide Setting":"Ukryj ustawienia",Screenshot:"Zrzut ekranu","Play Speed":"Prędkość odtwarzania","Aspect Ratio":"Współczynnik proporcji",Default:"Domyślny",Normal:"Normalny",Open:"Otwórz","Switch Video":"Przełącz wideo","Switch Subtitle":"Przełącz napisy",Fullscreen:"Pełny ekran","Exit Fullscreen":"Zamknij pełny ekran","Web Fullscreen":"Tryb pełnej strony","Exit Web Fullscreen":"Zamknij tryb pełnej strony","Mini Player":"Miniodtwarzacz","PIP Mode":"Tryb PiP","Exit PIP Mode":"Zamknij tryb PiP","PIP Not Supported":"Tryb PiP nieobsługiwany","Fullscreen Not Supported":"Pełny ekran nieobsługiwany","Subtitle Offset":"Przesunięcie napisów","Last Seen":"Ostatnio widziany","Jump Play":"Skocz do gry",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay nie jest dostępny"};return n("artplayer-i18n-pl",e),e})); diff --git a/packages/artplayer/dist/i18n/pl.mjs b/packages/artplayer/dist/i18n/pl.mjs index 5d48a1fc0..3e6273784 100644 --- a/packages/artplayer/dist/i18n/pl.mjs +++ b/packages/artplayer/dist/i18n/pl.mjs @@ -5,6 +5,11 @@ function o(e, i) { } } const a = { + "Context Menu": "Menu kontekstowe", + Lock: "Zablokuj", + Back: "Wstecz", + Settings: "Ustawienia", + Progress: "Postęp odtwarzania", "Video Info": "Informacje o wideo", Close: "Zamknij", "Video Load Failed": "Błąd ładowania wideo", diff --git a/packages/artplayer/dist/i18n/ru.js b/packages/artplayer/dist/i18n/ru.js index 7ae10b89e..518569d17 100644 --- a/packages/artplayer/dist/i18n/ru.js +++ b/packages/artplayer/dist/i18n/ru.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nRu=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Video Info":"Информация",Close:"Закрыть","Video Load Failed":"Ошибка загрузки видео",Volume:"Громкость",Play:"Играть",Pause:"Пауза",Rate:"Скорость",Mute:"Заглушить","Video Flip":"Развернуть видео",Horizontal:"Горизонтально",Vertical:"Вертикально",Reconnect:"Переподключенине","Show Setting":"Показать настройки","Hide Setting":"Скрыть настройки",Screenshot:"Скриншот","Play Speed":"Скорость воспроизведения","Aspect Ratio":"Соотношение сторон",Default:"По-умолчанию",Normal:"Нормальный",Open:"Открыть","Switch Video":"Переключить видео","Switch Subtitle":"Переключить субтитры",Fullscreen:"Полноэкранный режим","Exit Fullscreen":"Выход из полноэкранного режима","Web Fullscreen":"На все окно браузера","Exit Web Fullscreen":"Выход из режима полного окна","Mini Player":"Мини проигрыватель","PIP Mode":"Картинка в картинке","Exit PIP Mode":"Закрыть картинку в картинке","PIP Not Supported":"Картинка в картинке не поддерживается","Fullscreen Not Supported":"Полноэкранный режим не поддерживается","Subtitle Offset":"Настройка субтитров","Last Seen":"Последнее просмотренное","Jump Play":"Перейти",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay недоступен"};return t("artplayer-i18n-ru",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nRu=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"Контекстное меню",Lock:"Заблокировать",Back:"Назад",Settings:"Настройки",Progress:"Ход воспроизведения","Video Info":"Информация",Close:"Закрыть","Video Load Failed":"Ошибка загрузки видео",Volume:"Громкость",Play:"Играть",Pause:"Пауза",Rate:"Скорость",Mute:"Заглушить","Video Flip":"Развернуть видео",Horizontal:"Горизонтально",Vertical:"Вертикально",Reconnect:"Переподключенине","Show Setting":"Показать настройки","Hide Setting":"Скрыть настройки",Screenshot:"Скриншот","Play Speed":"Скорость воспроизведения","Aspect Ratio":"Соотношение сторон",Default:"По-умолчанию",Normal:"Нормальный",Open:"Открыть","Switch Video":"Переключить видео","Switch Subtitle":"Переключить субтитры",Fullscreen:"Полноэкранный режим","Exit Fullscreen":"Выход из полноэкранного режима","Web Fullscreen":"На все окно браузера","Exit Web Fullscreen":"Выход из режима полного окна","Mini Player":"Мини проигрыватель","PIP Mode":"Картинка в картинке","Exit PIP Mode":"Закрыть картинку в картинке","PIP Not Supported":"Картинка в картинке не поддерживается","Fullscreen Not Supported":"Полноэкранный режим не поддерживается","Subtitle Offset":"Настройка субтитров","Last Seen":"Последнее просмотренное","Jump Play":"Перейти",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay недоступен"};return t("artplayer-i18n-ru",e),e})); diff --git a/packages/artplayer/dist/i18n/ru.mjs b/packages/artplayer/dist/i18n/ru.mjs index 5ec8e27e7..641c37043 100644 --- a/packages/artplayer/dist/i18n/ru.mjs +++ b/packages/artplayer/dist/i18n/ru.mjs @@ -5,6 +5,11 @@ function i(e, t) { } } const o = { + "Context Menu": "Контекстное меню", + Lock: "Заблокировать", + Back: "Назад", + Settings: "Настройки", + Progress: "Ход воспроизведения", "Video Info": "Информация", Close: "Закрыть", "Video Load Failed": "Ошибка загрузки видео", diff --git a/packages/artplayer/dist/i18n/tr.js b/packages/artplayer/dist/i18n/tr.js index fd2100d60..105ec3125 100644 --- a/packages/artplayer/dist/i18n/tr.js +++ b/packages/artplayer/dist/i18n/tr.js @@ -1 +1 @@ -(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nTr=e())})(this,(function(){"use strict";function a(n,i){if(typeof window<"u"){const t=window;t[n]=i}}const e={"Video Info":"Video Bilgisi",Close:"Kapat","Video Load Failed":"Video Yüklenemedi",Volume:"Ses Seviyesi",Play:"Oynat",Pause:"Duraklat",Rate:"Hız",Mute:"Sessize Al","Video Flip":"Videoyu Çevir",Horizontal:"Yatay",Vertical:"Dikey",Reconnect:"Yeniden Bağlan","Show Setting":"Ayarları Göster","Hide Setting":"Ayarları Gizle",Screenshot:"Ekran Görüntüsü","Play Speed":"Oynatma Hızı","Aspect Ratio":"En Boy Oranı",Default:"Varsayılan",Normal:"Normal",Open:"Aç","Switch Video":"Video Değiştir","Switch Subtitle":"Altyazı Değiştir",Fullscreen:"Tam Ekran","Exit Fullscreen":"Tam Ekrandan Çık","Web Fullscreen":"Web Tam Ekran","Exit Web Fullscreen":"Web Tam Ekranından Çık","Mini Player":"Küçük Oynatıcı","PIP Mode":"PIP Modu","Exit PIP Mode":"PIP Modundan Çık","PIP Not Supported":"PIP Desteklenmiyor","Fullscreen Not Supported":"Tam Ekran Desteklenmiyor","Subtitle Offset":"Altyazı Kaydırma","Last Seen":"Son İzlenen","Jump Play":"Atla ve Oynat",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay Kullanılamıyor"};return a("artplayer-i18n-tr",e),e})); +(function(a,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(a=typeof globalThis<"u"?globalThis:a||self,a.artplayerI18nTr=e())})(this,(function(){"use strict";function a(n,i){if(typeof window<"u"){const t=window;t[n]=i}}const e={"Context Menu":"Bağlam menüsü",Lock:"Kilitle",Back:"Geri",Settings:"Ayarlar",Progress:"Oynatma ilerlemesi","Video Info":"Video Bilgisi",Close:"Kapat","Video Load Failed":"Video Yüklenemedi",Volume:"Ses Seviyesi",Play:"Oynat",Pause:"Duraklat",Rate:"Hız",Mute:"Sessize Al","Video Flip":"Videoyu Çevir",Horizontal:"Yatay",Vertical:"Dikey",Reconnect:"Yeniden Bağlan","Show Setting":"Ayarları Göster","Hide Setting":"Ayarları Gizle",Screenshot:"Ekran Görüntüsü","Play Speed":"Oynatma Hızı","Aspect Ratio":"En Boy Oranı",Default:"Varsayılan",Normal:"Normal",Open:"Aç","Switch Video":"Video Değiştir","Switch Subtitle":"Altyazı Değiştir",Fullscreen:"Tam Ekran","Exit Fullscreen":"Tam Ekrandan Çık","Web Fullscreen":"Web Tam Ekran","Exit Web Fullscreen":"Web Tam Ekranından Çık","Mini Player":"Küçük Oynatıcı","PIP Mode":"PIP Modu","Exit PIP Mode":"PIP Modundan Çık","PIP Not Supported":"PIP Desteklenmiyor","Fullscreen Not Supported":"Tam Ekran Desteklenmiyor","Subtitle Offset":"Altyazı Kaydırma","Last Seen":"Son İzlenen","Jump Play":"Atla ve Oynat",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay Kullanılamıyor"};return a("artplayer-i18n-tr",e),e})); diff --git a/packages/artplayer/dist/i18n/tr.mjs b/packages/artplayer/dist/i18n/tr.mjs index 3fd6fda66..6df0c887f 100644 --- a/packages/artplayer/dist/i18n/tr.mjs +++ b/packages/artplayer/dist/i18n/tr.mjs @@ -4,7 +4,12 @@ function l(e, a) { i[e] = a; } } -const n = { +const t = { + "Context Menu": "Bağlam menüsü", + Lock: "Kilitle", + Back: "Geri", + Settings: "Ayarlar", + Progress: "Oynatma ilerlemesi", "Video Info": "Video Bilgisi", Close: "Kapat", "Video Load Failed": "Video Yüklenemedi", @@ -42,7 +47,7 @@ const n = { AirPlay: "AirPlay", "AirPlay Not Available": "AirPlay Kullanılamıyor" }; -l("artplayer-i18n-tr", n); +l("artplayer-i18n-tr", t); export { - n as default + t as default }; diff --git a/packages/artplayer/dist/i18n/vi.js b/packages/artplayer/dist/i18n/vi.js index 5e2fedf11..02ae6c912 100644 --- a/packages/artplayer/dist/i18n/vi.js +++ b/packages/artplayer/dist/i18n/vi.js @@ -1 +1 @@ -(function(t,n){typeof exports=="object"&&typeof module<"u"?module.exports=n():typeof define=="function"&&define.amd?define(n):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nVi=n())})(this,(function(){"use strict";function t(e,i){if(typeof window<"u"){const h=window;h[e]=i}}const n={"Video Info":"Thông tin video",Close:"Đóng","Video Load Failed":"Tải video thất bại",Volume:"Âm lượng",Play:"Phát",Pause:"Tạm dừng",Rate:"Tốc độ",Mute:"Tắt tiếng","Video Flip":"Lật video",Horizontal:"Ngang",Vertical:"Dọc",Reconnect:"Kết nối lại","Show Setting":"Cài đặt","Hide Setting":"Ẩn cài đặt",Screenshot:"Chụp màn hình","Play Speed":"Tốc độ phát","Aspect Ratio":"Tỷ lệ khung hình",Default:"Mặc định",Normal:"Bình thường",Open:"Mở","Switch Video":"Chuyển video","Switch Subtitle":"Chuyển phụ đề",Fullscreen:"Toàn màn hình","Exit Fullscreen":"Thoát toàn màn hình","Web Fullscreen":"Toàn màn hình trình duyệt","Exit Web Fullscreen":"Thoát toàn màn hình trình duyệt","Mini Player":"Trình phát mini","PIP Mode":"Phát trong hình","Exit PIP Mode":"Thoát phát trong hình","PIP Not Supported":"Không hỗ trợ phát trong hình","Fullscreen Not Supported":"Không hỗ trợ toàn màn hình","Subtitle Offset":"Độ trễ phụ đề","Last Seen":"Lần xem cuối","Jump Play":"Nhảy đến đoạn phát",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay không khả dụng"};return t("artplayer-i18n-vi",n),n})); +(function(t,n){typeof exports=="object"&&typeof module<"u"?module.exports=n():typeof define=="function"&&define.amd?define(n):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nVi=n())})(this,(function(){"use strict";function t(e,i){if(typeof window<"u"){const h=window;h[e]=i}}const n={"Context Menu":"Menu ngữ cảnh",Lock:"Khóa",Back:"Quay lại",Settings:"Cài đặt",Progress:"Tiến trình phát","Video Info":"Thông tin video",Close:"Đóng","Video Load Failed":"Tải video thất bại",Volume:"Âm lượng",Play:"Phát",Pause:"Tạm dừng",Rate:"Tốc độ",Mute:"Tắt tiếng","Video Flip":"Lật video",Horizontal:"Ngang",Vertical:"Dọc",Reconnect:"Kết nối lại","Show Setting":"Cài đặt","Hide Setting":"Ẩn cài đặt",Screenshot:"Chụp màn hình","Play Speed":"Tốc độ phát","Aspect Ratio":"Tỷ lệ khung hình",Default:"Mặc định",Normal:"Bình thường",Open:"Mở","Switch Video":"Chuyển video","Switch Subtitle":"Chuyển phụ đề",Fullscreen:"Toàn màn hình","Exit Fullscreen":"Thoát toàn màn hình","Web Fullscreen":"Toàn màn hình trình duyệt","Exit Web Fullscreen":"Thoát toàn màn hình trình duyệt","Mini Player":"Trình phát mini","PIP Mode":"Phát trong hình","Exit PIP Mode":"Thoát phát trong hình","PIP Not Supported":"Không hỗ trợ phát trong hình","Fullscreen Not Supported":"Không hỗ trợ toàn màn hình","Subtitle Offset":"Độ trễ phụ đề","Last Seen":"Lần xem cuối","Jump Play":"Nhảy đến đoạn phát",AirPlay:"AirPlay","AirPlay Not Available":"AirPlay không khả dụng"};return t("artplayer-i18n-vi",n),n})); diff --git a/packages/artplayer/dist/i18n/vi.mjs b/packages/artplayer/dist/i18n/vi.mjs index 697bbcc38..2f4ecbae4 100644 --- a/packages/artplayer/dist/i18n/vi.mjs +++ b/packages/artplayer/dist/i18n/vi.mjs @@ -5,6 +5,11 @@ function h(n, t) { } } const i = { + "Context Menu": "Menu ngữ cảnh", + Lock: "Khóa", + Back: "Quay lại", + Settings: "Cài đặt", + Progress: "Tiến trình phát", "Video Info": "Thông tin video", Close: "Đóng", "Video Load Failed": "Tải video thất bại", diff --git a/packages/artplayer/dist/i18n/zh-tw.js b/packages/artplayer/dist/i18n/zh-tw.js index 3048834cf..0f57e24c1 100644 --- a/packages/artplayer/dist/i18n/zh-tw.js +++ b/packages/artplayer/dist/i18n/zh-tw.js @@ -1 +1 @@ -(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nZhTw=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Video Info":"統計訊息",Close:"關閉","Video Load Failed":"載入失敗",Volume:"音量",Play:"播放",Pause:"暫停",Rate:"速度",Mute:"靜音","Video Flip":"畫面翻轉",Horizontal:"水平",Vertical:"垂直",Reconnect:"重新連接","Show Setting":"顯示设置","Hide Setting":"隱藏设置",Screenshot:"截圖","Play Speed":"播放速度","Aspect Ratio":"畫面比例",Default:"默認",Normal:"正常",Open:"打開","Switch Video":"切換","Switch Subtitle":"切換字幕",Fullscreen:"全屏","Exit Fullscreen":"退出全屏","Web Fullscreen":"網頁全屏","Exit Web Fullscreen":"退出網頁全屏","Mini Player":"迷你播放器","PIP Mode":"開啟畫中畫","Exit PIP Mode":"退出畫中畫","PIP Not Supported":"不支持畫中畫","Fullscreen Not Supported":"不支持全屏","Subtitle Offset":"字幕偏移","Last Seen":"上次看到","Jump Play":"跳轉播放",AirPlay:"隔空播放","AirPlay Not Available":"隔空播放不可用"};return t("artplayer-i18n-zh-tw",e),e})); +(function(t,e){typeof exports=="object"&&typeof module<"u"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.artplayerI18nZhTw=e())})(this,(function(){"use strict";function t(i,n){if(typeof window<"u"){const o=window;o[i]=n}}const e={"Context Menu":"快捷選單",Lock:"鎖定",Back:"返回",Settings:"設定",Progress:"播放進度","Video Info":"統計訊息",Close:"關閉","Video Load Failed":"載入失敗",Volume:"音量",Play:"播放",Pause:"暫停",Rate:"速度",Mute:"靜音","Video Flip":"畫面翻轉",Horizontal:"水平",Vertical:"垂直",Reconnect:"重新連接","Show Setting":"顯示设置","Hide Setting":"隱藏设置",Screenshot:"截圖","Play Speed":"播放速度","Aspect Ratio":"畫面比例",Default:"默認",Normal:"正常",Open:"打開","Switch Video":"切換","Switch Subtitle":"切換字幕",Fullscreen:"全屏","Exit Fullscreen":"退出全屏","Web Fullscreen":"網頁全屏","Exit Web Fullscreen":"退出網頁全屏","Mini Player":"迷你播放器","PIP Mode":"開啟畫中畫","Exit PIP Mode":"退出畫中畫","PIP Not Supported":"不支持畫中畫","Fullscreen Not Supported":"不支持全屏","Subtitle Offset":"字幕偏移","Last Seen":"上次看到","Jump Play":"跳轉播放",AirPlay:"隔空播放","AirPlay Not Available":"隔空播放不可用"};return t("artplayer-i18n-zh-tw",e),e})); diff --git a/packages/artplayer/dist/i18n/zh-tw.mjs b/packages/artplayer/dist/i18n/zh-tw.mjs index b20c8dc69..f32c2f5a1 100644 --- a/packages/artplayer/dist/i18n/zh-tw.mjs +++ b/packages/artplayer/dist/i18n/zh-tw.mjs @@ -1,10 +1,15 @@ -function i(e, t) { +function o(e, t) { if (typeof window < "u") { const l = window; l[e] = t; } } -const o = { +const i = { + "Context Menu": "快捷選單", + Lock: "鎖定", + Back: "返回", + Settings: "設定", + Progress: "播放進度", "Video Info": "統計訊息", Close: "關閉", "Video Load Failed": "載入失敗", @@ -42,7 +47,7 @@ const o = { AirPlay: "隔空播放", "AirPlay Not Available": "隔空播放不可用" }; -i("artplayer-i18n-zh-tw", o); +o("artplayer-i18n-zh-tw", i); export { - o as default + i as default }; diff --git a/packages/artplayer/dist/icons.ts b/packages/artplayer/dist/icons.ts new file mode 100644 index 000000000..b97cf5662 --- /dev/null +++ b/packages/artplayer/dist/icons.ts @@ -0,0 +1,30 @@ +export interface Icons { + readonly loading: HTMLDivElement + readonly state: HTMLDivElement + readonly play: HTMLDivElement + readonly pause: HTMLDivElement + readonly check: HTMLDivElement + readonly volume: HTMLDivElement + readonly volumeClose: HTMLDivElement + readonly screenshot: HTMLDivElement + readonly setting: HTMLDivElement + readonly pip: HTMLDivElement + readonly arrowLeft: HTMLDivElement + readonly arrowRight: HTMLDivElement + readonly playbackRate: HTMLDivElement + readonly aspectRatio: HTMLDivElement + readonly config: HTMLDivElement + readonly lock: HTMLDivElement + readonly flip: HTMLDivElement + readonly unlock: HTMLDivElement + readonly fullscreenOff: HTMLDivElement + readonly fullscreenOn: HTMLDivElement + readonly fullscreenWebOff: HTMLDivElement + readonly fullscreenWebOn: HTMLDivElement + readonly switchOn: HTMLDivElement + readonly switchOff: HTMLDivElement + readonly error: HTMLDivElement + readonly close: HTMLDivElement + readonly airplay: HTMLDivElement + readonly [key: string]: HTMLDivElement +} diff --git a/packages/artplayer/dist/language.cts b/packages/artplayer/dist/language.cts new file mode 100644 index 000000000..ab9320684 --- /dev/null +++ b/packages/artplayer/dist/language.cts @@ -0,0 +1,5 @@ +import type { I18n } from './i18n.js' + +declare const language: NonNullable +// eslint-disable-next-line no-restricted-syntax -- Preserve the language object's CommonJS value export. +export = language diff --git a/packages/artplayer/dist/language.mts b/packages/artplayer/dist/language.mts new file mode 100644 index 000000000..3b243cb0a --- /dev/null +++ b/packages/artplayer/dist/language.mts @@ -0,0 +1 @@ +export { default } from './language.cjs' diff --git a/packages/artplayer/dist/legacy/language.ts b/packages/artplayer/dist/legacy/language.ts new file mode 100644 index 000000000..34de69188 --- /dev/null +++ b/packages/artplayer/dist/legacy/language.ts @@ -0,0 +1,4 @@ +import type { I18n } from '../i18n' + +declare const language: NonNullable +export default language diff --git a/packages/artplayer/dist/option.ts b/packages/artplayer/dist/option.ts new file mode 100644 index 000000000..022d146bf --- /dev/null +++ b/packages/artplayer/dist/option.ts @@ -0,0 +1,331 @@ +import type Artplayer from './artplayer' +import type { ComponentInput, ComponentOption } from './component' +import type { CssVar } from './cssVar' +import type { I18n } from './i18n' +import type { Icons } from './icons' +import type { PluginFactory } from './plugin' +import type { Quality } from './quality' +import type { Setting } from './setting' +import type { Subtitle } from './subtitle' + +export type CustomType + = | 'flv' + | 'm3u8' + | 'hls' + | 'ts' + | 'mpd' + | 'torrent' + | (string & Record) + +export interface Thumbnails { + /** + * The thumbnail image url + */ + url: string + + /** + * The thumbnail item number + */ + number?: number + + /** + * The thumbnail column size + */ + column?: number + + /** + * The thumbnail width + */ + width?: number + + /** + * The thumbnail height + */ + height?: number + + /** + * The thumbnail scale + */ + scale?: number +} + +/** Constructor input; Option retains its historical required URL/read types. */ +export interface OptionInput extends Omit { + url?: string + controls?: ComponentInput[] + layers?: ComponentInput[] + contextmenu?: ComponentInput[] +} + +export interface Option { + /** + * The player id + */ + id?: string + + /** + * The container mounted by the player + */ + container: string | HTMLDivElement + + /** + * Video url + */ + url: string + + /** + * Video poster image url + */ + poster?: string + + /** + * Video url type + */ + type?: CustomType + + /** + * Player color theme + */ + theme?: string + + /** + * Player language + */ + lang?: keyof I18n + + /** + * Player default volume + */ + volume?: number + + /** + * Whether live broadcast mode + */ + isLive?: boolean + + /** + * Whether video muted + */ + muted?: boolean + + /** + * Whether video auto play + */ + autoplay?: boolean + + /** + * Whether player auto resize + */ + autoSize?: boolean + + /** + * Whether player auto run mini mode + */ + autoMini?: boolean + + /** + * Whether video auto loop + */ + loop?: boolean + + /** + * Whether show video flip button + */ + flip?: boolean + + /** + * Whether show video playback rate button + */ + playbackRate?: boolean + + /** + * Whether show video aspect ratio button + */ + aspectRatio?: boolean + + /** + * Whether show video screenshot button + */ + screenshot?: boolean + + /** + * Whether show video setting button + */ + setting?: boolean + + /** + * Whether to enable player hotkey + */ + hotkey?: boolean + + /** + * Whether show video pip button + */ + pip?: boolean + + /** + * Do you want to run only one player at a time + */ + mutex?: boolean + + /** + * Whether use backdrop in UI + */ + backdrop?: boolean + + /** + * Whether show video window fullscreen button + */ + fullscreen?: boolean + + /** + * Whether show video web fullscreen button + */ + fullscreenWeb?: boolean + + /** + * Whether to enable player subtitle offset + */ + subtitleOffset?: boolean + + /** + * Whether to enable player mini progress bar + */ + miniProgressBar?: boolean + + /** + * Whether use SSR function + */ + useSSR?: boolean + + /** + * Whether use playsInline in mobile + */ + playsInline?: boolean + + /** + * Whether use lock in mobile + */ + lock?: boolean + + /** + * Whether use gesture in mobile + */ + gesture?: boolean + + /** + * Whether use fast forward in mobile + */ + fastForward?: boolean + + /** + * Whether use auto playback + */ + autoPlayback?: boolean + + /** + * Whether use auto orientation in mobile + */ + autoOrientation?: boolean + + /** + * Whether use airplay + */ + airplay?: boolean + + /** + * Custom video proxy + */ + proxy?: (this: Artplayer, art: Artplayer) => HTMLCanvasElement | HTMLVideoElement | undefined + + /** + * Custom plugin list + */ + plugins?: PluginFactory[] + + /** + * Custom layer list + */ + layers?: ComponentOption[] + + /** + * Custom contextmenu list + */ + contextmenu?: ComponentOption[] + + /** + * Custom control list + */ + controls?: ComponentOption[] + + /** + * Custom setting list + */ + settings?: Setting[] + + /** + * Custom video quality list + */ + quality?: Quality[] + + /** + * Custom highlight list + */ + highlight?: { + /** + * The highlight time + */ + time: number + + /** + * The highlight text + */ + text: string + }[] + + /** + * Custom thumbnail + */ + thumbnails?: Thumbnails + + /** + * Custom subtitle option + */ + subtitle?: Subtitle + + /** + * Other video attribute + */ + moreVideoAttr?: Partial unknown + ? never + : K]: HTMLVideoElement[K] + }>> + + /** + * Custom i18n + */ + i18n?: I18n + + /** + * Custom default icons + */ + icons?: { + [key in keyof Icons]?: HTMLElement | string + } + + /** + * Custom css variables + */ + cssVar?: Partial + + /** + * Custom video type function + */ + customType?: Partial< + Record< + CustomType, + (this: Artplayer, video: HTMLVideoElement, url: string, art: Artplayer) => unknown | Promise + > + > +} diff --git a/packages/artplayer/dist/playback.ts b/packages/artplayer/dist/playback.ts new file mode 100644 index 000000000..b9452c046 --- /dev/null +++ b/packages/artplayer/dist/playback.ts @@ -0,0 +1,6 @@ +/** Accurate playback method view; assign an existing player without a runtime wrapper. */ +export interface PlaybackControls { + play: () => Promise + pause: () => void + toggle: () => Promise | void +} diff --git a/packages/artplayer/dist/player.ts b/packages/artplayer/dist/player.ts new file mode 100644 index 000000000..14051a790 --- /dev/null +++ b/packages/artplayer/dist/player.ts @@ -0,0 +1,113 @@ +import type { CssVar } from './cssVar' +import type { CustomType, Thumbnails } from './option' +import type { Quality } from './quality' + +export type AspectRatio = 'default' | '4:3' | '16:9' | (`${number}:${number}` & Record) +export type PlaybackRate = 0.5 | 0.75 | 1.0 | 1.25 | 1.5 | 1.75 | 2.0 | (number & Record) +export type Flip = 'normal' | 'horizontal' | 'vertical' | (string & Record) +export type State = 'standard' | 'mini' | 'pip' | 'fullscreen' | 'fullscreenWeb' + +export declare class Player { + get aspectRatio(): AspectRatio + set aspectRatio(ratio: AspectRatio) + + get state(): State + set state(state: State) + + get type(): CustomType + set type(name: CustomType) + + get playbackRate(): PlaybackRate + set playbackRate(rate: PlaybackRate) + + get currentTime(): number + set currentTime(time: number) + + get duration(): number + get played(): number + get playing(): boolean + + get flip(): Flip + set flip(state: Flip) + + get fullscreen(): boolean + set fullscreen(state: boolean) + + get fullscreenWeb(): boolean + set fullscreenWeb(state: boolean) + + get loaded(): number + get loadedTime(): number + + get mini(): boolean + set mini(state: boolean) + + get pip(): boolean + set pip(state: boolean) + + get poster(): string + set poster(url: string) + + get rect(): DOMRect + get bottom(): number + get height(): number + get left(): number + get right(): number + get top(): number + get width(): number + get x(): number + get y(): number + + set seek(time: number) + get seek(): number + + set forward(time: number) + get forward(): number + + set backward(time: number) + get backward(): number + + get url(): string + set url(url: string) + + get volume(): number + set volume(percentage: number) + + get muted(): boolean + set muted(state: boolean) + + get theme(): string + set theme(theme: string) + + get subtitleOffset(): number + set subtitleOffset(time: number) + + get switch(): string + set switch(url: string) + + get quality(): Quality[] + set quality(quality: Quality[]) + + get thumbnails(): Thumbnails + set thumbnails(thumbnails: Thumbnails) + + pause(): void + play(): Promise + /** Legacy signature; runtime preserves pause's synchronous result or play's Promise. */ + toggle(): void + + attr(key: string, value?: unknown): unknown + cssVar(key: T, value?: CssVar[T]): CssVar[T] + + switchUrl(url: string): Promise + switchQuality(url: string): Promise + + getDataURL(): Promise + getBlobUrl(): Promise + screenshot(name?: string): Promise + + airplay(): void + autoSize(): void + autoHeight(): void + reset(): void +} diff --git a/packages/artplayer/dist/plugin.ts b/packages/artplayer/dist/plugin.ts new file mode 100644 index 000000000..1f4a61ee6 --- /dev/null +++ b/packages/artplayer/dist/plugin.ts @@ -0,0 +1,10 @@ +import type Artplayer from './artplayer' + +export type PluginFactory = (this: Host, art: Host) => Result + +/** Augment this interface with installed plugin results; augmentation does not register a plugin. */ +export interface Plugins { + /** Legacy signature: synchronous factories return this registry; Promise factories return a Promise of it. */ + add: (plugin: PluginFactory) => Promise + [name: string]: unknown +} diff --git a/packages/artplayer/dist/quality.ts b/packages/artplayer/dist/quality.ts new file mode 100644 index 000000000..04058141a --- /dev/null +++ b/packages/artplayer/dist/quality.ts @@ -0,0 +1,16 @@ +export interface Quality { + /** + * Whether the default is selected + */ + default?: boolean + + /** + * Html string of quality + */ + html: string | HTMLElement + + /** + * Video quality url + */ + url: string +} diff --git a/packages/artplayer/dist/runtime.cts b/packages/artplayer/dist/runtime.cts new file mode 100644 index 000000000..77fa28d37 --- /dev/null +++ b/packages/artplayer/dist/runtime.cts @@ -0,0 +1,54 @@ +import type * as Definition from './runtime.js' + +declare const Artplayer: typeof Definition.default +// eslint-disable-next-line ts/no-redeclare -- CJS constructor value and instance type share the export. +type Artplayer = Definition.default + +// eslint-disable-next-line ts/no-redeclare, ts/no-namespace -- Named types share the existing CommonJS export. +declare namespace Artplayer { + type ArtplayerConstructor = Definition.ArtplayerConstructor + type OptionInput = Definition.OptionInput + type Option = Definition.Option + type Events = Definition.Events + type Plugins = Definition.Plugins + type PluginFactory = Definition.PluginFactory + type PluginHost = Definition.PluginHost + type ProxyHost = Definition.ProxyHost + type CustomTypeHost = Definition.CustomTypeHost + type LayerHost = Definition.LayerHost + type ControlHost = Definition.ControlHost + type ContextmenuHost = Definition.ContextmenuHost + type PluginRegistration = Definition.PluginRegistration + type Component = Definition.Component + type Controls = Definition.Controls + type Setting = Definition.Setting + type Subtitle = Definition.Subtitle + type Notice = Definition.Notice + type Utils = Definition.Utils + type MediaSurface = Definition.MediaSurface + type NativeMedia = Definition.NativeMedia + type CanvasMedia = Definition.CanvasMedia + type Player = Definition.Player + type Template = Definition.Template + type Icons = Definition.Icons + type Config = Definition.Config + type EventRegistry = Definition.EventRegistry + type Storage = Definition.Storage + type I18n = Definition.I18n + type Hotkey = Definition.Hotkey + type Languages = Definition.Languages + type Dictionary = Definition.Dictionary + type QualityItem = Definition.QualityItem + type SettingItem = Definition.SettingItem + type ComponentInput = Definition.ComponentInput + type ComponentOption = Definition.ComponentOption + type ControlInput = Definition.ControlInput + type ControlOption = Definition.ControlOption + type SelectorItem = Definition.SelectorItem + type SubtitleCue = Definition.SubtitleCue + type SubtitleOption = Definition.SubtitleOption + type Emitter> = Definition.Emitter +} + +// eslint-disable-next-line no-restricted-syntax -- Preserve the actual CommonJS constructor export. +export = Artplayer diff --git a/packages/artplayer/dist/runtime.mts b/packages/artplayer/dist/runtime.mts new file mode 100644 index 000000000..afba2a834 --- /dev/null +++ b/packages/artplayer/dist/runtime.mts @@ -0,0 +1,2 @@ +export { default } from './runtime.cjs' +export type * from './runtime.js' diff --git a/packages/artplayer/dist/runtime.ts b/packages/artplayer/dist/runtime.ts new file mode 100644 index 000000000..fe19bce2e --- /dev/null +++ b/packages/artplayer/dist/runtime.ts @@ -0,0 +1,125 @@ +import type LegacyArtplayer from './artplayer' +import type { Emitter } from './emitter' +import type { OptionInput as LegacyOptionInput } from './option' +import type { PluginFactory as LegacyPluginFactory, Plugins as LegacyPlugins } from './plugin' +import type { ComponentInput, Component as ComponentView, ControlInput, Controls as ControlsView } from './runtime/component' +import type { ContextmenuHost, ControlHost, CustomTypeHost, LayerHost, PluginHost, ProxyHost } from './runtime/construction' +import type { Events } from './runtime/events' +import type { MediaSurface } from './runtime/media' +import type { OptionInput as OptionInputView, Option as OptionView } from './runtime/option' +import type { Player } from './runtime/player' +import type { PluginFactory as FactoryView, PluginRegistration, Plugins as PluginsView } from './runtime/plugin' +import type { Config, EventRegistry, Hotkey, I18n, Scheme, Storage, ValidatorPath } from './runtime/services' +import type { Setting as SettingView } from './runtime/setting' +import type { Notice as NoticeView, Subtitle as SubtitleView } from './runtime/subtitle' +import type { Icons, Template } from './runtime/template' +import type { Utils } from './runtime/utils' + +export type { Emitter } from './emitter' +export type { ComponentInput, ComponentOption, ControlInput, ControlOption, SelectorItem } from './runtime/component' +export type { ContextmenuHost, ControlHost, CustomTypeHost, LayerHost, PluginHost, ProxyHost } from './runtime/construction' +export type { Events } from './runtime/events' +export type { CanvasMedia, MediaSurface, NativeMedia } from './runtime/media' +export type { Player, QualityItem } from './runtime/player' +export type { PluginRegistration } from './runtime/plugin' +export type { Config, Dictionary, EventRegistry, Hotkey, I18n, Languages, Storage } from './runtime/services' +export type { SettingItem } from './runtime/setting' +export type { SubtitleCue, SubtitleOption } from './runtime/subtitle' +export type { Icons, Template } from './runtime/template' +export type { Utils } from './runtime/utils' + +export type PluginFactory = FactoryView +export interface OptionInput extends Omit, 'plugins' | 'proxy' | 'customType' | 'layers' | 'controls' | 'contextmenu'> { + plugins?: PluginFactory[] + proxy?: (this: ProxyHost, art: ProxyHost) => MediaSurface + customType?: Record unknown) | undefined> + layers?: ComponentInput[] + controls?: ControlInput[] + contextmenu?: ComponentInput[] +} +export interface Option extends OptionView {} +export interface Component extends ComponentView {} +export interface Controls extends ControlsView {} +export interface Setting extends SettingView {} +export interface Subtitle extends SubtitleView, Omit {} +export interface Notice extends NoticeView { art: Artplayer } + +/** Augment with installed results. Factories are not wrapped or converted. */ +export interface PluginAdd { + (plugin: FactoryView): PluginRegistration + (plugin: LegacyPluginFactory): PluginRegistration +} + +type LegacyPluginResults = { + [Name in keyof LegacyPlugins as string extends Name ? never : number extends Name ? never : Name extends keyof PluginsView ? never : Name]: LegacyPlugins[Name] +} + +export interface Plugins extends Omit, 'add'>, LegacyPluginResults { + add: PluginAdd + [name: string]: unknown +} + +/** Public view of the existing constructor; this interface emits no runtime fields. */ +interface Artplayer extends Player, Emitter { + constructor: ArtplayerConstructor + id: number + option: Option + isLock: boolean + isReady: boolean + isFocus: boolean + isInput: boolean + isRotate: boolean + isDestroy: boolean + flv?: unknown + m3u8?: unknown + hls?: unknown + ts?: unknown + mpd?: unknown + torrent?: unknown + template: Template + events: EventRegistry + storage: Storage + icons: Icons + i18n: I18n + notice: Notice + /** The descriptor installer has no public instance members. */ + player: object + layers: Component + controls: Controls + contextmenu: Component & { init: () => void } + subtitle: Subtitle + info: Component & { init: () => void } + loading: Component + hotkey: Hotkey + mask: Component + setting: Setting + plugins: Plugins + readonly query: Template['query'] + readonly proxy: EventRegistry['proxy'] + readonly video: MediaSurface + reset: () => void + destroy: (removeHtml?: boolean) => void +} + +type StaticOptions = Pick>> + +export interface ArtplayerConstructor extends StaticOptions { + new (option: OptionInput, readyCallback?: (this: Artplayer, art: Artplayer) => unknown): Artplayer + new (option: LegacyOptionInput, readyCallback?: (this: Artplayer, art: Artplayer) => unknown): Artplayer + readonly prototype: Artplayer + readonly instances: Artplayer[] + readonly version: string + readonly config: Config + readonly utils: Utils + readonly scheme: Record + readonly Emitter: new >(...args: unknown[]) => Emitter + readonly validator: (option: T, scheme: Scheme, paths?: ValidatorPath) => T + readonly kindOf: (value: unknown) => string + readonly html: string + readonly option: Option +} + +// eslint-disable-next-line ts/no-redeclare -- One existing constructor value and its instance view. +declare const Artplayer: ArtplayerConstructor + +export default Artplayer diff --git a/packages/artplayer/dist/runtime/component.ts b/packages/artplayer/dist/runtime/component.ts new file mode 100644 index 000000000..f23ae4b3f --- /dev/null +++ b/packages/artplayer/dist/runtime/component.ts @@ -0,0 +1,65 @@ +export type EventCleanup = () => void + +export interface SelectorItem { + html: string | HTMLElement | number + value?: string | number + default?: boolean + readonly $control_option?: SelectorItem[] + readonly $control_item?: HTMLDivElement + readonly $control_value?: HTMLDivElement +} + +export interface ComponentOption { + html?: string | HTMLElement | number + disable?: boolean + name?: string + index?: number + style?: Partial + tooltip?: string | number + position?: string + selector?: SelectorItem[] + click?: (this: Host, component: Component, event: Event) => unknown + mounted?: (this: Host, element: HTMLDivElement) => unknown + beforeUnmount?: (this: Host, element: HTMLDivElement) => unknown + onSelect?: (this: Host, item: SelectorItem, element: HTMLDivElement, event: Event) => unknown +} + +export type ComponentInput = ComponentOption | ((art: Host) => ComponentOption) + +export interface ControlOption extends Omit, 'position'> { + position: 'top' | 'left' | 'right' +} + +export type ControlInput = ControlOption | ((art: Host) => ControlOption) + +export interface ComponentEntry { + $ref: HTMLDivElement + events: EventCleanup[] + option: ComponentOption +} + +export interface Component { + id: number + art: Host + name?: string + $parent?: HTMLElement + cache: Map> + show: boolean + toggle: () => void + add: (input: ComponentInput) => HTMLDivElement | undefined + remove: (name: string) => void + update: (option: ComponentOption) => ReturnType + selector?: (option: ComponentOption, element: HTMLDivElement, events: EventCleanup[]) => void +} + +export interface Controls extends Omit, 'add' | 'update' | 'selector'> { + isHover: boolean + timer: number + setting?: HTMLDivElement + thumbnails?: HTMLDivElement + init: () => void + add: (input: ControlInput) => undefined + update: (option: ComponentOption) => undefined + check: (target?: SelectorItem) => void + selector: (option: ComponentOption, element: HTMLDivElement, events: EventCleanup[]) => void +} diff --git a/packages/artplayer/dist/runtime/construction.ts b/packages/artplayer/dist/runtime/construction.ts new file mode 100644 index 000000000..0dc902200 --- /dev/null +++ b/packages/artplayer/dist/runtime/construction.ts @@ -0,0 +1,19 @@ +import type { Emitter } from '../emitter' +import type Artplayer from '../runtime' +import type { Events } from './events' +import type { Player } from './player' + +/** Safe fields before Template returns; video/query/proxy getters are not usable yet. */ +export interface ProxyHost extends Emitter, Pick {} + +// Mapped types collapse distinct getter/setter types; preserve Player directly. +type Pending = Player & Omit & Partial> +type AfterPlayer = 'layers' | 'controls' | 'contextmenu' | 'subtitle' | 'info' | 'loading' | 'hotkey' | 'mask' | 'setting' | 'plugins' + +/** URL assignment awaits its owned delay before invoking customType. */ +export type CustomTypeHost = Artplayer +export type LayerHost = Pending +export type ControlHost = Pending> +export type ContextmenuHost = Pending> +/** Constructor factories run before the Plugins registry is assigned to the player. */ +export type PluginHost = Pending<'plugins'> diff --git a/packages/artplayer/dist/runtime/events.ts b/packages/artplayer/dist/runtime/events.ts new file mode 100644 index 000000000..0d5e26888 --- /dev/null +++ b/packages/artplayer/dist/runtime/events.ts @@ -0,0 +1,26 @@ +import type { Events as LegacyEvents } from '../events' +import type { SubtitleCue, SubtitleOption } from './subtitle' + +type NativeEvents = { [Name in Extract]: [event: Event] } + +interface BuiltinEvents { + [name: `video:${string}`]: [event: Event] + 'document:keydown': [KeyboardEvent] + 'document:mousemove': [MouseEvent] + 'document:mouseup': [MouseEvent] + 'mousemove': [MouseEvent] + 'click': [MouseEvent] + 'blur': [Event] + 'error': [error: unknown, attempt: number] + 'fullscreenError': [error: unknown] + 'aspectRatio': [string] + 'flip': [string] + 'seek': [time: number, requestedTime: number | string] + 'setBar': [type: string, percentage: number, event?: MouseEvent | TouchEvent] + 'subtitleBeforeUpdate': [cues: SubtitleCue[]] + 'subtitleAfterUpdate': [cues: SubtitleCue[]] + 'subtitleLoad': [cues: SubtitleCue[], option: SubtitleOption | null] +} + +/** Legacy custom event augmentation is retained; builtin payload corrections take precedence. */ +export interface Events extends Omit, NativeEvents, BuiltinEvents, Record {} diff --git a/packages/artplayer/dist/runtime/media.ts b/packages/artplayer/dist/runtime/media.ts new file mode 100644 index 000000000..335620f65 --- /dev/null +++ b/packages/artplayer/dist/runtime/media.ts @@ -0,0 +1,41 @@ +export type MediaState = Pick & { + readonly playing?: boolean +} + +export interface PlaybackMethods { + play: () => PlayResult + pause: () => PauseResult +} + +export interface OptionalMediaCapabilities { + readonly textTracks?: ArrayLike + readonly error?: unknown + requestPictureInPicture?: () => Promise + requestVideoFrameCallback?: (callback: VideoFrameRequestCallback) => number + cancelVideoFrameCallback?: (handle: number) => void + webkitEnterFullscreen?: () => void + webkitExitFullscreen?: () => void + readonly webkitSupportsFullscreen?: boolean + webkitShowPlaybackTargetPicker?: () => void + webkitSupportsPresentationMode?: (mode: string) => boolean + webkitSetPresentationMode?: (mode: string) => void + readonly webkitPresentationMode?: string + readonly webkitDisplayingFullscreen?: boolean +} + +export type NativeMedia = Omit & OptionalMediaCapabilities + +export type CanvasMedia = HTMLCanvasElement & MediaState & PlaybackMethods & OptionalMediaCapabilities & { + src: string | null + readonly currentSrc: string | null + readonly videoWidth: number + readonly videoHeight: number + readonly buffered: TimeRanges + volume: number + muted: boolean + playbackRate: number + load: () => unknown +} + +/** Check optional capabilities before calling them on a native or proxy surface. */ +export type MediaSurface = NativeMedia | CanvasMedia diff --git a/packages/artplayer/dist/runtime/option.ts b/packages/artplayer/dist/runtime/option.ts new file mode 100644 index 000000000..9b7f8d477 --- /dev/null +++ b/packages/artplayer/dist/runtime/option.ts @@ -0,0 +1,28 @@ +import type { OptionInput as LegacyOptionInput, Thumbnails } from '../option' +import type { ComponentInput, ControlInput } from './component' +import type { MediaSurface } from './media' +import type { PluginFactory } from './plugin' +import type { Languages } from './services' +import type { SettingItem } from './setting' +import type { SubtitleOption } from './subtitle' + +/** Callback receivers are the unchanged player instance selected by this view. */ +export interface OptionInput extends Omit { + container: string | HTMLDivElement + proxy?: (this: Host, art: Host) => MediaSurface | undefined + plugins?: PluginFactory[] + layers?: ComponentInput[] + controls?: ControlInput[] + contextmenu?: ComponentInput[] + settings?: SettingItem[] + customType?: Record unknown) | undefined> + i18n?: Languages + icons?: Record +} + +/** Defaults are merged once; later setters may replace thumbnails with a partial input. */ +export interface Option extends Omit>, 'proxy' | 'subtitle' | 'thumbnails'> { + proxy: OptionInput['proxy'] + subtitle: SubtitleOption + thumbnails: Thumbnails +} diff --git a/packages/artplayer/dist/runtime/player.ts b/packages/artplayer/dist/runtime/player.ts new file mode 100644 index 000000000..1180dc68d --- /dev/null +++ b/packages/artplayer/dist/runtime/player.ts @@ -0,0 +1,78 @@ +import type { Thumbnails } from '../option' +import type { State } from '../player' +import type { MediaSurface } from './media' + +export interface QualityItem { + html: string | HTMLElement + url: string + default?: boolean +} + +/** Player-facing descriptors; native/proxy method results retain their identity. */ +export interface Player { + get currentTime(): number + set currentTime(time: number | string) + readonly duration: number + get seek(): undefined + set seek(time: number | string) + get forward(): undefined + set forward(time: number) + get backward(): undefined + set backward(time: number) + get switch(): undefined + set switch(url: string) + get quality(): undefined + set quality(items: QualityItem[]) + get url(): string | null + set url(value: string) + get state(): State + set state(value: string) + get pip(): Element | null | boolean + set pip(value: boolean) + /** The descriptor may be absent before metadata installs the available mode. */ + fullscreen?: boolean + fullscreenWeb: boolean + mini: boolean + volume: number + muted: boolean + playbackRate: number + aspectRatio: string + flip: string + poster: string + theme: string + type: string + subtitleOffset: number + thumbnails: Thumbnails + readonly loaded: number + readonly loadedTime: number + readonly played: number + readonly playing: boolean + readonly rect: DOMRect + readonly bottom: number + readonly height: number + readonly left: number + readonly right: number + readonly top: number + readonly width: number + readonly x: number + readonly y: number + play: () => Promise>> + pause: () => ReturnType + toggle: () => Promise>> | ReturnType + switchUrl: (url: string) => Promise + switchQuality: (url: string) => Promise + autoSize: () => void + autoHeight: () => void + airplay: () => void + getDataURL: () => Promise + getBlobUrl: () => Promise + screenshot: (name?: string) => Promise + attr: { + (key: PropertyKey): unknown + (key: PropertyKey, value: unknown): unknown + } + cssVar: { + (key: string): string + (key: string, value: unknown): string | void + } +} diff --git a/packages/artplayer/dist/runtime/plugin.ts b/packages/artplayer/dist/runtime/plugin.ts new file mode 100644 index 000000000..3192f3c11 --- /dev/null +++ b/packages/artplayer/dist/runtime/plugin.ts @@ -0,0 +1,13 @@ +export type PluginFactory = (this: Host, art: Host) => Result + +export type PluginRegistration + = unknown extends Result ? Registry | Promise + : Result extends Promise ? Promise : Registry + +/** The same registry is returned immediately or after its Promise factory settles. */ +export interface Plugins { + art: Host + id: number + add: (plugin: PluginFactory) => PluginRegistration + next: (plugin: PluginFactory, result: unknown) => this +} diff --git a/packages/artplayer/dist/runtime/services.ts b/packages/artplayer/dist/runtime/services.ts new file mode 100644 index 000000000..50c4f507f --- /dev/null +++ b/packages/artplayer/dist/runtime/services.ts @@ -0,0 +1,57 @@ +export interface Config { + properties: string[] + methods: string[] + events: string[] + prototypes: string[] +} + +export type Disposer = () => void +export type Listener = EventListenerOrEventListenerObject | null + +export interface EventRegistry { + destroyEvents: Set + proxy: { + (target: EventTarget, name: string, callback: Listener, option?: boolean | AddEventListenerOptions | null): Disposer + (target: EventTarget, name: string[], callback: Listener, option?: boolean | AddEventListenerOptions | null): Disposer[] + (target: EventTarget, name: string | string[], callback: Listener, option?: boolean | AddEventListenerOptions | null): Disposer | Disposer[] + } + hover: (target: EventTarget, mouseenter?: (event: Event) => unknown, mouseleave?: (event: Event) => unknown) => void + remove: (dispose: Disposer) => void + destroy: () => void + bindGlobalEvents: (source?: { window?: Window, document?: Document }) => void +} + +export interface Storage { + name: string + settings: Record + get: (key?: PropertyKey) => unknown + set: (key: PropertyKey, value: unknown) => void + del: (key: PropertyKey) => void + clear: () => void +} + +export type Dictionary = Record +export type Languages = Record + +export interface I18n { + art: Host + languages: Languages + language: Dictionary + init: () => void + get: (key: string) => string + update: (value: Languages) => void +} + +export type HotkeyCallback = (this: Host, event: KeyboardEvent) => unknown + +export interface Hotkey { + art: Host + keys: Record[]> + init: () => void + add: (key: string, callback: HotkeyCallback) => this + remove: (key: string, callback: HotkeyCallback) => this +} + +export type ValidatorPath = (string | number)[] +export type Validator = (value: unknown, type: string, paths: ValidatorPath) => unknown +export type Scheme = string | Validator | Scheme[] | { [key: string]: Scheme } diff --git a/packages/artplayer/dist/runtime/setting.ts b/packages/artplayer/dist/runtime/setting.ts new file mode 100644 index 000000000..dda910320 --- /dev/null +++ b/packages/artplayer/dist/runtime/setting.ts @@ -0,0 +1,58 @@ +export type SettingContent = string | HTMLElement | number +export type SettingRange = [value?: number, min?: number, max?: number, step?: number] +export type SettingCallback = (this: Host, item: SettingItem, element: HTMLDivElement, event: Event) => unknown + +export interface SettingItem { + name?: string + html?: SettingContent + icon?: SettingContent + tooltip?: SettingContent + width?: number + value?: string | number + default?: boolean + switch?: boolean + range?: SettingRange + selector?: SettingItem[] + mounted?: (this: Host, element: HTMLDivElement, item: SettingItem) => unknown + onClick?: SettingCallback + onSwitch?: SettingCallback + onRange?: SettingCallback + onChange?: SettingCallback + onSelect?: SettingCallback + readonly $parent?: SettingItem + readonly $parents?: SettingItem[] + readonly $option?: SettingItem[] + readonly $events?: (() => void)[] + readonly $formatted?: boolean + readonly $item?: HTMLDivElement + readonly $icon?: HTMLDivElement + readonly $html?: HTMLDivElement + readonly $tooltip?: HTMLDivElement + readonly $switch?: HTMLDivElement + readonly $range?: HTMLInputElement +} + +export interface Setting { + id: number + art: Host + name: string + $parent: HTMLElement + cache: Map[], HTMLDivElement> + active: SettingItem[] | null + option: SettingItem[] + readonly builtin: SettingItem[] + show: boolean + toggle: () => void + traverse: (callback: (item: SettingItem) => void, option?: SettingItem[]) => void + check: (target?: SettingItem | null) => void + format: (option?: SettingItem[], parent?: SettingItem, parents?: SettingItem[], names?: string[]) => void + find: (name?: string) => SettingItem | null + resize: () => void + inactivate: (item: SettingItem) => void + remove: (name: string) => void + update: (item: SettingItem) => SettingItem + add: >(item: Item, option?: SettingItem[]) => Item + createHeader: (item: SettingItem) => void + createItem: (item: SettingItem, isUpdate?: boolean) => void + render: (option?: SettingItem[]) => void +} diff --git a/packages/artplayer/dist/runtime/subtitle.ts b/packages/artplayer/dist/runtime/subtitle.ts new file mode 100644 index 000000000..0fe6c0350 --- /dev/null +++ b/packages/artplayer/dist/runtime/subtitle.ts @@ -0,0 +1,38 @@ +import type { Subtitle as SubtitleInput } from '../subtitle' + +export type SubtitleOption = Required + +export interface SubtitleCue extends TextTrackCue { + text: string + originalStartTime?: number + originalEndTime?: number +} + +export interface SubtitleTrack extends HTMLTrackElement { offset?: number } + +export interface Subtitle { + name: string + option: SubtitleOption | null + destroyEvent: () => unknown + url: string + readonly textTrack: TextTrack | undefined + readonly activeCues: SubtitleCue[] + readonly cues: SubtitleCue[] + show: boolean + toggle: () => void + style: { + (styles: Partial): HTMLDivElement + (key: string, value: string | number): HTMLDivElement + } + update: () => void + switch: (url: string, option?: SubtitleInput) => Promise + init: (option: SubtitleOption) => Promise + createTrack: (kind: string, url: string) => void +} + +export interface Notice { + timer: number | null + get show(): boolean + set show(value: string | Error | false) + destroy: () => void +} diff --git a/packages/artplayer/dist/runtime/template.ts b/packages/artplayer/dist/runtime/template.ts new file mode 100644 index 000000000..0ac9b2409 --- /dev/null +++ b/packages/artplayer/dist/runtime/template.ts @@ -0,0 +1,42 @@ +import type { MediaSurface } from './media' + +/** Query results remain nullable for caller-supplied SSR templates. */ +export interface Template { + art: Host + $container: HTMLDivElement + $player: HTMLDivElement | null + $video: Media + $track: HTMLTrackElement | null + $poster: HTMLDivElement | null + $subtitle: HTMLDivElement | null + $danmuku: HTMLDivElement | null + $bottom: HTMLDivElement | null + $progress: HTMLDivElement | null + $controls: HTMLDivElement | null + $controlsLeft: HTMLDivElement | null + $controlsCenter: HTMLDivElement | null + $controlsRight: HTMLDivElement | null + $layer: HTMLDivElement | null + $loading: HTMLDivElement | null + $notice: HTMLDivElement | null + $noticeInner: HTMLDivElement | null + $mask: HTMLDivElement | null + $state: HTMLDivElement | null + $setting: HTMLDivElement | null + $info: HTMLDivElement | null + $infoPanel: HTMLDivElement | null + $infoClose: HTMLDivElement | null + $contextmenu: HTMLDivElement | null + $mini?: HTMLElement + query: (selector: string) => ElementType | null + init: () => void + destroy: (removeHtml: boolean) => void +} + +export type IconName = 'loading' | 'state' | 'play' | 'pause' | 'check' | 'volume' | 'volumeClose' + | 'screenshot' | 'setting' | 'pip' | 'arrowLeft' | 'arrowRight' | 'playbackRate' | 'aspectRatio' + | 'config' | 'lock' | 'flip' | 'unlock' | 'fullscreenOff' | 'fullscreenOn' | 'fullscreenWebOff' + | 'fullscreenWebOn' | 'switchOn' | 'switchOff' | 'error' | 'close' | 'airplay' + +/** Default getters create fresh icon wrappers; unknown custom keys may be absent. */ +export type Icons = Readonly> & { readonly [name: string]: HTMLElement | undefined } diff --git a/packages/artplayer/dist/runtime/utils.ts b/packages/artplayer/dist/runtime/utils.ts new file mode 100644 index 000000000..50e38626f --- /dev/null +++ b/packages/artplayer/dist/runtime/utils.ts @@ -0,0 +1,67 @@ +interface StyledElement { style: CSSStyleDeclaration } +interface EventPathSource { + target: EventTarget | null + composedPath?: () => EventTarget[] +} +type StackFrame = ((...args: never[]) => unknown) | (abstract new (...args: never[]) => object) + +export interface Utils { + isBrowser: boolean + userAgent: string + isMobile: boolean + isSafari: boolean + isIOS: boolean + isIOS13: boolean + query: (selector: string, parent?: ParentNode) => T | null + queryAll: (selector: string, parent?: ParentNode) => T[] + addClass: (target: Pick, className: string) => void + removeClass: (target: Pick, className: string) => void + hasClass: (target: Pick, className: string) => boolean + append: (parent: Element, child: unknown) => Element | ChildNode | null + remove: (child: T) => T + replaceElement: (newChild: T, oldChild: Node) => T + siblings: (target: Element) => Element[] + inverseClass: (target: Element, className: string) => void + createElement: { + (tag: K): HTMLElementTagNameMap[K] + (tag: string): HTMLElement + } + setStyle: (element: T, key: PropertyKey, value: unknown) => T + setStyles: (element: T, styles: object) => T + getStyle: { + (element: Element, key: string, numberType?: true): number + (element: Element, key: string, numberType: false): string + (element: Element, key: string, numberType: boolean): number | string + } + setStyleText: (id: string, cssText: string) => void + getRect: (element: Pick) => DOMRect + tooltip: (target: Element, message: string | number, position?: string) => void + isInViewport: (target: Pick, offset?: number) => boolean + includeFromEvent: (event: EventPathSource, target: EventTarget | null | undefined) => boolean + getSafeAreaInsets: () => { top: number, right: number, bottom: number, left: number } + srtToVtt: (text: string) => string + vttToBlob: (text: string) => string + assToVtt: (text: string) => string + getExt: (url: string) => string + download: (url: string, name: string) => void + loadImg: (url: string, scale?: number) => Promise + errorHandle: (condition: T, message?: string) => T + silencePromise: (value: T) => T extends Promise ? Promise : T + def: (object: T, name: PropertyKey, descriptor: PropertyDescriptor & object & ThisType) => T + has: (object: object, name: PropertyKey) => boolean + get: (object: object, name: PropertyKey) => PropertyDescriptor | undefined + mergeDeep: (...objects: T) => T[number] + sleep: (milliseconds?: number) => Promise + /** The wrapper preserves its call receiver; the old context argument is ignored. */ + debounce: (callback: (this: Receiver, ...args: Args) => unknown, duration: number, context?: object) => (this: Receiver, ...args: Args) => void + throttle: (callback: (this: Receiver, ...args: Args) => unknown, duration: number) => (this: Receiver, ...args: Args) => void + clamp: (number: number, a: number, b: number) => number + secondToTime: (second: number) => string + escape: (text: string) => string + unescape: (text: string) => string + capitalize: (text: string) => string + ArtPlayerError: new (message?: string, context?: StackFrame) => Error + getIcon: (key?: string, html?: string | HTMLElement) => HTMLElement + getComposedPath: (event: EventPathSource) => EventTarget[] + supportsFlex: () => boolean +} diff --git a/packages/artplayer/dist/setting.ts b/packages/artplayer/dist/setting.ts new file mode 100644 index 000000000..739dd5908 --- /dev/null +++ b/packages/artplayer/dist/setting.ts @@ -0,0 +1,95 @@ +import type Artplayer from './artplayer' + +export interface SettingOption extends Omit { + html: string + icon: string | undefined + tooltip: string | undefined + $item: HTMLDivElement + $icon: HTMLDivElement | undefined + $html: HTMLDivElement + $tooltip: HTMLDivElement | undefined + $switch: HTMLDivElement | undefined + $range: HTMLInputElement | undefined + $parent: SettingOption | undefined + $parents: SettingOption[] + $option: SettingOption[] + $events: Array<() => void> + $formatted: boolean +} + +export interface Setting { + /** + * Html string or html element of setting name + */ + html: string | HTMLElement + + /** + * Html string or html element of setting icon + */ + icon?: string | HTMLElement + + /** + * The width of setting + */ + width?: number + + /** + * The tooltip of setting + */ + tooltip?: string | HTMLElement + + /** + * Whether the default is selected + */ + default?: boolean + + /** + * Custom selector list + */ + selector?: Setting[] + + /** + * When the setting was mounted + */ + mounted?: (this: Artplayer, panel: HTMLDivElement, item: Setting) => void + + /** + * When selector item click + */ + onSelect?: (this: Artplayer, item: SettingOption, element: HTMLDivElement, event: Event) => void + + /** + * Custom switch item + */ + switch?: boolean + + /** + * When switch item click + */ + onSwitch?: (this: Artplayer, item: SettingOption, element: HTMLDivElement, event: Event) => void + + /** + * Custom range item + */ + range?: [value?: number, min?: number, max?: number, step?: number] + + /** + * When range item change + */ + onRange?: (this: Artplayer, item: SettingOption, element: HTMLDivElement, event: Event) => void + + /** + * When range item change in real time + */ + onChange?: (this: Artplayer, item: SettingOption, element: HTMLDivElement, event: Event) => void + + /** + * When range item change in real time + */ + onClick?: (this: Artplayer, item: SettingOption, element: HTMLDivElement, event: Event) => void + + /** + * Allow custom properties + */ + [key: string]: any +} diff --git a/packages/artplayer/dist/subtitle.ts b/packages/artplayer/dist/subtitle.ts new file mode 100644 index 000000000..9783d155c --- /dev/null +++ b/packages/artplayer/dist/subtitle.ts @@ -0,0 +1,36 @@ +export interface Subtitle { + /** + * The subtitle url + */ + url?: string + + /** + * The subtitle name + */ + name?: string + + /** + * The subtitle type + */ + type?: 'vtt' | 'srt' | 'ass' | (string & Record) + + /** + * The subtitle style object + */ + style?: Partial + + /** + * The subtitle encoding, default utf-8 + */ + encoding?: string + + /** + * Whether use escape, default true + */ + escape?: boolean + + /** + * Change the vtt text + */ + onVttLoad?: (vtt: string) => string +} diff --git a/packages/artplayer/dist/template.ts b/packages/artplayer/dist/template.ts new file mode 100644 index 000000000..50c346a65 --- /dev/null +++ b/packages/artplayer/dist/template.ts @@ -0,0 +1,27 @@ +export interface Template { + readonly html: string + readonly $container: HTMLDivElement + readonly $player: HTMLDivElement + readonly $video: HTMLVideoElement + readonly $track: HTMLTrackElement + readonly $poster: HTMLDivElement + readonly $subtitle: HTMLDivElement + readonly $danmuku: HTMLDivElement + readonly $bottom: HTMLDivElement + readonly $progress: HTMLDivElement + readonly $controls: HTMLDivElement + readonly $controlsLeft: HTMLDivElement + readonly $controlsCenter: HTMLDivElement + readonly $controlsRight: HTMLDivElement + readonly $layer: HTMLDivElement + readonly $loading: HTMLDivElement + readonly $notice: HTMLDivElement + readonly $noticeInner: HTMLDivElement + readonly $mask: HTMLDivElement + readonly $state: HTMLDivElement + readonly $setting: HTMLDivElement + readonly $info: HTMLDivElement + readonly $infoPanel: HTMLDivElement + readonly $infoClose: HTMLDivElement + readonly $contextmenu: HTMLDivElement +} diff --git a/packages/artplayer/dist/utils.ts b/packages/artplayer/dist/utils.ts new file mode 100644 index 000000000..63229ca7f --- /dev/null +++ b/packages/artplayer/dist/utils.ts @@ -0,0 +1,73 @@ +export interface Utils { + isBrowser: boolean + userAgent: string + isMobile: boolean + isSafari: boolean + isIOS: boolean + isIOS13: boolean + + query: (selector: string, parent?: Document | HTMLElement) => T | null + queryAll: (selector: string, parent?: Document | HTMLElement) => T[] + addClass: (target: HTMLElement, className: string) => void + removeClass: (target: HTMLElement, className: string) => void + hasClass: (target: HTMLElement, className: string) => boolean + append: (target: HTMLElement, child: HTMLElement | string) => Element | ChildNode + remove: (target: HTMLElement) => HTMLElement + replaceElement: (newChild: HTMLElement, oldChild: HTMLElement) => HTMLElement + siblings: (target: HTMLElement) => HTMLElement[] + inverseClass: (target: HTMLElement, className: string) => void + createElement: (tag: K) => HTMLElementTagNameMap[K] + setStyle: ( + element: HTMLElement, + key: T, + value: string | CSSStyleDeclaration[T], + ) => HTMLElement + setStyles: (element: HTMLElement, styles: Partial) => HTMLElement + getStyle: { + (element: HTMLElement, key: keyof CSSStyleDeclaration, numberType?: true): number + (element: HTMLElement, key: keyof CSSStyleDeclaration, numberType: false): string + } + setStyleText: (id: string, cssText: string) => void + getRect: (el: HTMLElement) => { top: number, left: number, width: number, height: number } + tooltip: (target: HTMLElement, msg: string, pos?: string) => void + isInViewport: (target: HTMLElement, offset?: number) => boolean + includeFromEvent: (event: Event, target: HTMLElement) => boolean + getSafeAreaInsets: () => { top: number, right: number, bottom: number, left: number } + + srtToVtt: (srtText: string) => string + vttToBlob: (vttText: string) => string + assToVtt: (assText: string) => string + + getExt: (url: string) => string + download: (url: string, name: string) => void + loadImg: (url: string, scale?: number) => Promise + + errorHandle: (condition: T, msg: string) => T extends true ? T : never + silencePromise: (value: T) => T extends Promise ? Promise : T + def: { + /** Historical string-key signature; runtime returns obj. */ + (obj: object, name: string, value: unknown): void + (obj: T, name: PropertyKey, value: PropertyDescriptor & ThisType): T + } + has: (obj: object, name: PropertyKey) => boolean + get: (obj: object, name: PropertyKey) => PropertyDescriptor | undefined + mergeDeep: (...args: T) => T[number] + + sleep: (ms?: number) => Promise + /** Historical return type; runtime discards the callback result and ignores context. */ + debounce: any>(func: F, wait: number, context?: object) => (...args: Parameters) => ReturnType + /** Historical return type; runtime discards the callback result. */ + throttle: any>(func: F, wait: number) => (...args: Parameters) => ReturnType + + clamp: (num: number, a: number, b: number) => number + secondToTime: (second: number) => string + escape: (str: string) => string + unescape: (str: string) => string + capitalize: (str: string) => string + + ArtPlayerError: new (message?: string, context?: ((...args: never[]) => unknown) | (abstract new (...args: never[]) => object)) => Error + + getIcon: (key?: string, html?: string | HTMLElement) => HTMLElement + getComposedPath: (event: Event) => EventTarget[] + supportsFlex: () => boolean +} diff --git a/packages/artplayer/public/i18n.ts b/packages/artplayer/public/i18n.ts index 4986660c1..214c5dec2 100644 --- a/packages/artplayer/public/i18n.ts +++ b/packages/artplayer/public/i18n.ts @@ -15,10 +15,15 @@ type I18nKeys | (string & Record) interface I18nValue { + 'Context Menu'?: string + 'Lock'?: string 'Video Info': string 'Close': string 'Video Load Failed': string 'Volume': string + 'Progress'?: string + 'Back'?: string + 'Settings'?: string 'Play': string 'Pause': string 'Rate': string diff --git a/packages/artplayer/src/accessibility/button.ts b/packages/artplayer/src/accessibility/button.ts new file mode 100644 index 000000000..194e8bec5 --- /dev/null +++ b/packages/artplayer/src/accessibility/button.ts @@ -0,0 +1,48 @@ +import type ResourceScope from '../lifecycle/scope' +import { listen } from '../lifecycle/resources' +import { claimKey, plainKey } from './keyboard' + +/** Preserve the existing click path and keep owned keys out of player hotkeys. */ +export function keyboardButton(scope: ResourceScope, element: HTMLElement, activate = () => element.click(), active = () => true): void { + if (scope.closed) + return + if (!element.hasAttribute('role')) + element.setAttribute('role', 'button') + if (!element.hasAttribute('tabindex')) + element.tabIndex = 0 + let space = false + const enabled = () => active() && element.getAttribute('aria-disabled') !== 'true' && !element.hasAttribute('disabled') + const own = (event: KeyboardEvent) => (event.composedPath()[0] || event.target) === element + listen(scope, element, 'keydown', (value) => { + const event = value as KeyboardEvent + if (!own(event) || !plainKey(event) || event.defaultPrevented) + return + if (event.key === 'Enter') { + claimKey(event) + if (!event.repeat && enabled()) + activate() + } + else if (event.key === ' ') { + claimKey(event) + if (!event.repeat && enabled()) + space = true + } + }) + listen(scope, element, 'keyup', (value) => { + const event = value as KeyboardEvent + if (event.key !== ' ') + return + const armed = space + space = false + if (armed && own(event) && plainKey(event) && !event.defaultPrevented && enabled() && element.ownerDocument.activeElement === element) { + claimKey(event) + activate() + } + }) + listen(scope, element, 'blur', () => { + space = false + }) + scope.add(() => { + space = false + }) +} diff --git a/packages/artplayer/src/accessibility/focus.ts b/packages/artplayer/src/accessibility/focus.ts new file mode 100644 index 000000000..2455eebeb --- /dev/null +++ b/packages/artplayer/src/accessibility/focus.ts @@ -0,0 +1,50 @@ +import type ResourceScope from '../lifecycle/scope' +import { listen } from '../lifecycle/resources' + +/** Keep keyboard visibility separate from the existing pointer focus flags. */ +export function focusVisibility(scope: ResourceScope, root: HTMLElement, show: () => void): () => boolean { + let keyboard = true + let document: Document | undefined + let documentScope: ResourceScope | undefined + const focused = () => !scope.closed && keyboard && root.contains(root.ownerDocument.activeElement) + const update = () => { + const visible = focused() + const previous = root.classList.contains('art-keyboard-focus') + root.classList.toggle('art-keyboard-focus', visible) + if (visible && !previous) + show() + } + const key = () => { + keyboard = true + update() + } + const pointer = () => { + keyboard = false + update() + } + const bindDocument = () => { + if (document === root.ownerDocument) + return + documentScope?.dispose() + document = root.ownerDocument + documentScope = scope.child() + listen(documentScope, document, 'keydown', key, { capture: true }) + listen(documentScope, document, 'mousedown', pointer, { capture: true }) + listen(documentScope, document, 'touchstart', pointer, { capture: true, passive: true }) + } + bindDocument() + listen(scope, root, 'keydown', key, { capture: true }) + listen(scope, root, 'mousedown', pointer, { capture: true }) + listen(scope, root, 'touchstart', pointer, { capture: true, passive: true }) + listen(scope, root, 'focusin', () => { + bindDocument() + update() + }) + listen(scope, root, 'focusout', () => { + root.classList.remove('art-keyboard-focus') + }) + scope.add(() => { + root.classList.remove('art-keyboard-focus') + }) + return focused +} diff --git a/packages/artplayer/src/accessibility/keyboard.ts b/packages/artplayer/src/accessibility/keyboard.ts new file mode 100644 index 000000000..ed02535cc --- /dev/null +++ b/packages/artplayer/src/accessibility/keyboard.ts @@ -0,0 +1,14 @@ +const handled = new WeakSet() + +export function claimKey(event: KeyboardEvent): void { + handled.add(event) + event.preventDefault() +} + +export function isClaimedKey(event: KeyboardEvent): boolean { + return handled.has(event) +} + +export function plainKey(event: KeyboardEvent): boolean { + return !event.altKey && !event.ctrlKey && !event.metaKey && !event.isComposing && event.keyCode !== 229 +} diff --git a/packages/artplayer/src/accessibility/moved-focus.ts b/packages/artplayer/src/accessibility/moved-focus.ts new file mode 100644 index 000000000..4c8129021 --- /dev/null +++ b/packages/artplayer/src/accessibility/moved-focus.ts @@ -0,0 +1,9 @@ +/** Restore the same focused descendant after DOM reparenting. */ +export function captureMovedFocus(root: HTMLElement): () => void { + const focused = root.ownerDocument?.activeElement as HTMLElement | null | undefined + const inside = focused && root.contains(focused) + return () => { + if (inside && focused.isConnected && root.contains(focused) && focused.ownerDocument.activeElement === focused.ownerDocument.body) + focused.focus({ preventScroll: true }) + } +} diff --git a/packages/artplayer/src/accessibility/overlay-focus.ts b/packages/artplayer/src/accessibility/overlay-focus.ts new file mode 100644 index 000000000..73412e998 --- /dev/null +++ b/packages/artplayer/src/accessibility/overlay-focus.ts @@ -0,0 +1,26 @@ +const origins = new WeakMap() + +export function setOverlayOrigin(overlay: HTMLElement, origin?: HTMLElement): void { + if (origin) + origins.set(overlay, origin) + else + origins.delete(overlay) +} + +export function resolveFocusOrigin(target: HTMLElement): HTMLElement { + const visited = new Set() + let current = target + while (!visited.has(current)) { + visited.add(current) + let element: HTMLElement | null = current + let origin: HTMLElement | undefined + while (element && !origin) { + origin = origins.get(element) + element = element.parentElement + } + if (!origin) + return current + current = origin + } + return target +} diff --git a/packages/artplayer/src/accessibility/player-focus.ts b/packages/artplayer/src/accessibility/player-focus.ts new file mode 100644 index 000000000..6b5e3ceef --- /dev/null +++ b/packages/artplayer/src/accessibility/player-focus.ts @@ -0,0 +1,22 @@ +import type { ComponentHost } from '../component/types' +import { getScope, isClosing } from '../lifecycle/instance' + +const owned = new WeakSet() + +export function focusPlayer(art: Pick): void { + const player = art.template.$player + if (isClosing(art) || !player.isConnected) + return + if (!player.hasAttribute('tabindex')) { + player.setAttribute('tabindex', '-1') + if (!owned.has(player)) { + owned.add(player) + getScope(art).add(() => { + owned.delete(player) + if (player.getAttribute('tabindex') === '-1') + player.removeAttribute('tabindex') + }) + } + } + player.focus({ preventScroll: true }) +} diff --git a/packages/artplayer/src/accessibility/slider.ts b/packages/artplayer/src/accessibility/slider.ts new file mode 100644 index 000000000..fcac1b0c5 --- /dev/null +++ b/packages/artplayer/src/accessibility/slider.ts @@ -0,0 +1,55 @@ +import type ResourceScope from '../lifecycle/scope' +import { listen } from '../lifecycle/resources' +import { claimKey, plainKey } from './keyboard' + +interface Range { + min: number + max: number + value: number + step: number + text: (value: number) => string +} + +const directions = new Map([['ArrowRight', 1], ['ArrowUp', 1], ['ArrowLeft', -1], ['ArrowDown', -1], ['PageUp', 10], ['PageDown', -10]]) + +export function keyboardSlider(scope: ResourceScope, element: HTMLElement, label: string, read: () => Range, write: (value: number) => void, orientation = 'horizontal'): () => void { + const valid = (range: Range) => [range.min, range.max, range.value, range.step].every(Number.isFinite) && range.max > range.min && range.step > 0 + const clamp = (value: number, range: Range) => Math.min(range.max, Math.max(range.min, value)) + const update = () => { + if (scope.closed) + return + const range = read() + const enabled = valid(range) + const value = enabled ? clamp(range.value, range) : 0 + element.setAttribute('aria-disabled', String(!enabled)) + element.setAttribute('aria-valuemin', String(enabled ? range.min : 0)) + element.setAttribute('aria-valuemax', String(enabled ? range.max : 0)) + element.setAttribute('aria-valuenow', String(value)) + element.setAttribute('aria-valuetext', range.text(value)) + } + if (scope.closed) + return update + element.setAttribute('role', 'slider') + element.tabIndex = 0 + element.setAttribute('aria-label', label) + element.setAttribute('aria-orientation', orientation) + listen(scope, element, 'keydown', (value) => { + const event = value as KeyboardEvent + if ((event.composedPath()[0] || event.target) !== element || !plainKey(event) || event.defaultPrevented) + return + const direction = directions.get(event.key) + if (direction === undefined && event.key !== 'Home' && event.key !== 'End') + return + claimKey(event) + const range = read() + if (!valid(range)) { + update() + return + } + const next = event.key === 'Home' ? range.min : event.key === 'End' ? range.max : clamp(range.value, range) + direction! * range.step + write(clamp(next, range)) + update() + }) + update() + return update +} diff --git a/packages/artplayer/src/accessibility/suspend-focus.ts b/packages/artplayer/src/accessibility/suspend-focus.ts new file mode 100644 index 000000000..488a03be3 --- /dev/null +++ b/packages/artplayer/src/accessibility/suspend-focus.ts @@ -0,0 +1,57 @@ +import type ResourceScope from '../lifecycle/scope' + +export function suspendFocus(scope: ResourceScope, root: HTMLElement): void { + const original = new Map() + const inert = root.hasAttribute('inert') + const hidden = root.getAttribute('aria-hidden') + const restore = (element: HTMLElement, value: string | null) => { + if (element.getAttribute('tabindex') !== '-1') + return + if (value === null) + element.removeAttribute('tabindex') + else + element.setAttribute('tabindex', value) + } + scope.add(() => { + for (const [element, value] of original) + restore(element, value) + original.clear() + if (!inert && root.getAttribute('inert') === '') + root.removeAttribute('inert') + if (root.getAttribute('aria-hidden') === 'true') { + if (hidden === null) + root.removeAttribute('aria-hidden') + else + root.setAttribute('aria-hidden', hidden) + } + }) + if (scope.closed) + return + if (!inert) + root.setAttribute('inert', '') + root.setAttribute('aria-hidden', 'true') + const update = () => { + if (scope.closed) + return + for (const [element, value] of original) { + if (!root.contains(element)) { + restore(element, value) + original.delete(element) + } + } + for (const element of root.querySelectorAll('[tabindex],button,input,select,textarea,a[href],[contenteditable]')) { + if (!original.has(element)) { + original.set(element, element.getAttribute('tabindex')) + element.setAttribute('tabindex', '-1') + } + } + } + update() + if (typeof MutationObserver !== 'undefined') { + const observer = new MutationObserver(update) + observer.observe(root, { childList: true, subtree: true }) + scope.add(() => { + observer.disconnect() + }) + } +} diff --git a/packages/artplayer/src/component/focus.ts b/packages/artplayer/src/component/focus.ts new file mode 100644 index 000000000..8f4f0c0ae --- /dev/null +++ b/packages/artplayer/src/component/focus.ts @@ -0,0 +1,50 @@ +import type { ComponentHost } from './types' +import { focusPlayer } from '../accessibility/player-focus' +import { isClosing } from '../lifecycle/instance' + +interface FocusOwner { + name?: string + art: ComponentHost + cache: Map +} + +const pending = new WeakSet() +const focusable = '[tabindex],button,input,select,textarea,a[href],[contenteditable]' + +function targetIn(element: HTMLElement): HTMLElement | undefined { + const targets = [element, ...element.querySelectorAll(focusable)] + return targets.find((target) => { + if (!target.matches(focusable) || target.tabIndex < 0 || target.matches(':disabled') || target.closest('[inert]') || target.getAttribute('aria-disabled') === 'true' || !target.getClientRects().length) + return false + const style = target.ownerDocument.defaultView?.getComputedStyle(target) + return style?.visibility !== 'hidden' && style?.visibility !== 'collapse' + }) +} + +export function captureComponentFocus(owner: FocusOwner, element?: HTMLElement, replacement?: string): () => void { + const doc = element?.ownerDocument + const focused = doc?.activeElement + if (!['control', 'contextmenu'].includes(owner.name ?? '') || pending.has(owner) || !element || !doc || !focused || !element.contains(focused)) + return () => {} + const player = owner.art.template.$player + const controls = Array.from(player.querySelectorAll(`.art-${owner.name}`)) + const index = controls.indexOf(element) + const neighbors = [...controls.slice(index + 1), ...controls.slice(0, index).reverse()] + pending.add(owner) + return () => { + pending.delete(owner) + if (isClosing(owner.art) || !player.isConnected || doc.activeElement !== doc.body) + return + const next = replacement ? owner.cache.get(replacement)?.$ref : undefined + for (const candidate of [...(next ? [next] : []), ...neighbors]) { + if (!player.contains(candidate)) + continue + const target = targetIn(candidate) + if (target) { + target.focus({ preventScroll: true }) + return + } + } + focusPlayer(owner.art) + } +} diff --git a/packages/artplayer/src/contextmenu/aspectRatio.ts b/packages/artplayer/src/contextmenu/aspectRatio.ts index a7ad1d2dc..49ea81243 100644 --- a/packages/artplayer/src/contextmenu/aspectRatio.ts +++ b/packages/artplayer/src/contextmenu/aspectRatio.ts @@ -1,6 +1,7 @@ import type { ContextmenuFactory, ContextmenuOption } from './types' import { controlEvents } from '../control/resources' import { inverseClass, query } from '../utils' +import { keyboardChoices, updateChoices } from './choices' export default function aspectRatio(option: ContextmenuOption): ContextmenuFactory { return (art) => { @@ -12,10 +13,11 @@ export default function aspectRatio(option: ContextmenuOption): ContextmenuFacto const html = ASPECT_RATIO.map( item => `${item === 'default' ? i18n.get('Default') : item}`, ).join('') + const label = i18n.get('Aspect Ratio') return { ...option, - html: `${i18n.get('Aspect Ratio')}: ${html}`, + html: `${label}: ${html}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : undefined if (value) { @@ -29,10 +31,12 @@ export default function aspectRatio(option: ContextmenuOption): ContextmenuFacto if ($default) { inverseClass($default, 'art-current') } + keyboardChoices($panel, label) on('aspectRatio', (value) => { const $current = Array.from($panel.querySelectorAll('span')).find(item => item.dataset.value === value) if ($current) { inverseClass($current, 'art-current') + updateChoices($panel) } }) }, diff --git a/packages/artplayer/src/contextmenu/choices.ts b/packages/artplayer/src/contextmenu/choices.ts new file mode 100644 index 000000000..e246ec7a3 --- /dev/null +++ b/packages/artplayer/src/contextmenu/choices.ts @@ -0,0 +1,20 @@ +import { keyboardButton } from '../accessibility/button' +import { entryScope } from '../component/resources' + +export function updateChoices(panel: HTMLElement): void { + for (const item of panel.querySelectorAll('[data-value]')) + item.setAttribute('aria-pressed', String(item.classList.contains('art-current'))) +} + +export function keyboardChoices(panel: HTMLElement, label: string): void { + const scope = entryScope(panel) + if (scope.closed) + return + panel.setAttribute('role', 'group') + panel.setAttribute('aria-label', label) + for (const item of panel.querySelectorAll('[data-value]')) { + keyboardButton(scope, item) + item.setAttribute('aria-label', `${label}: ${item.textContent?.trim() ?? ''}`) + } + updateChoices(panel) +} diff --git a/packages/artplayer/src/contextmenu/flip.ts b/packages/artplayer/src/contextmenu/flip.ts index 3b1d065aa..77dc2db06 100644 --- a/packages/artplayer/src/contextmenu/flip.ts +++ b/packages/artplayer/src/contextmenu/flip.ts @@ -1,6 +1,7 @@ import type { ContextmenuFactory, ContextmenuOption } from './types' import { controlEvents } from '../control/resources' import { capitalize, inverseClass, query } from '../utils' +import { keyboardChoices, updateChoices } from './choices' export default function flip(option: ContextmenuOption): ContextmenuFactory { return (art) => { @@ -10,10 +11,11 @@ export default function flip(option: ContextmenuOption): ContextmenuFactory { } = art const html = FLIP.map(item => `${i18n.get(capitalize(item))}`).join('') + const label = i18n.get('Video Flip') return { ...option, - html: `${i18n.get('Video Flip')}: ${html}`, + html: `${label}: ${html}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : undefined if (value) { @@ -27,10 +29,12 @@ export default function flip(option: ContextmenuOption): ContextmenuFactory { if ($default) { inverseClass($default, 'art-current') } + keyboardChoices($panel, label) on('flip', (value) => { const $current = Array.from($panel.querySelectorAll('span')).find(item => item.dataset.value === value) if ($current) { inverseClass($current, 'art-current') + updateChoices($panel) } }) }, diff --git a/packages/artplayer/src/contextmenu/index.ts b/packages/artplayer/src/contextmenu/index.ts index 52ac0fa67..450ede32f 100644 --- a/packages/artplayer/src/contextmenu/index.ts +++ b/packages/artplayer/src/contextmenu/index.ts @@ -1,13 +1,16 @@ import type { ContextmenuHost } from './types' -import { ownEntry } from '../component/resources' +import { ownEntry, releaseEntry } from '../component/resources' import { controlEvents } from '../control/resources' -import { getRect, includeFromEvent, isMobile, setStyles } from '../utils' +import { isClosing } from '../lifecycle/instance' +import { includeFromEvent, isMobile } from '../utils' import Component from '../utils/component' import aspectRatio from './aspectRatio' import close from './close' import flip from './flip' import info from './info' +import { contextmenuKeyboard } from './keyboard' import playbackRate from './playbackRate' +import { positionContextmenu } from './position' import version from './version' export default class Contextmenu extends Component { @@ -82,32 +85,22 @@ export default class Contextmenu extends Component { this.add(option.contextmenu[index]!) } + if (isClosing(this.art)) + return + releaseEntry($contextmenu) + const scope = ownEntry(this.art, $contextmenu) + const open = (x: number, y: number) => { + this.show = true + if (!scope.closed && !isClosing(this.art) && this.show) + positionContextmenu(this.art, x, y) + } + const keyboard = contextmenuKeyboard(this, open) + proxy($player, 'contextmenu', (event) => { - if (!this.art.constructor.CONTEXTMENU) + if (!keyboard.pointer(event)) return event.preventDefault() - - this.show = true - - const mouseX = event.clientX - const mouseY = event.clientY - const { height: cHeight, width: cWidth, left: cLeft, top: cTop } = getRect($player) - const { height: mHeight, width: mWidth } = getRect($contextmenu) - let menuLeft = mouseX - cLeft - let menuTop = mouseY - cTop - - if (mouseX + mWidth > cLeft + cWidth) { - menuLeft = cWidth - mWidth - } - - if (mouseY + mHeight > cTop + cHeight) { - menuTop = cHeight - mHeight - } - - setStyles($contextmenu, { - top: `${menuTop}px`, - left: `${menuLeft}px`, - }) + open(event.clientX, event.clientY) }) proxy($player, 'click', (event) => { diff --git a/packages/artplayer/src/contextmenu/keyboard.ts b/packages/artplayer/src/contextmenu/keyboard.ts new file mode 100644 index 000000000..aa7145da2 --- /dev/null +++ b/packages/artplayer/src/contextmenu/keyboard.ts @@ -0,0 +1,144 @@ +import type Contextmenu from './index' +import { claimKey, plainKey } from '../accessibility/keyboard' +import { resolveFocusOrigin, setOverlayOrigin } from '../accessibility/overlay-focus' +import { focusPlayer } from '../accessibility/player-focus' +import { entryScope } from '../component/resources' +import { isClosing } from '../lifecycle/instance' +import { listen, timeout } from '../lifecycle/resources' + +function editable(target: EventTarget | null): boolean { + const element = target as HTMLElement | null + return !!element && (['INPUT', 'TEXTAREA', 'SELECT'].includes(element.tagName) || element.isContentEditable) +} + +function available(element: HTMLElement): boolean { + const visibility = element.ownerDocument.defaultView?.getComputedStyle(element).visibility + return element.isConnected && !element.matches(':disabled') && !element.closest('[inert]') && element.getAttribute('aria-disabled') !== 'true' && element.getClientRects().length > 0 && visibility !== 'hidden' && visibility !== 'collapse' +} + +export function contextmenuKeyboard(menu: Contextmenu, open: (x: number, y: number) => void) { + const { art } = menu + const { $player, $contextmenu } = art.template + const scope = entryScope($contextmenu) + const active = () => !scope.closed && !isClosing(art) + let origin: HTMLElement | undefined + let hadFocus = false + let prefix = '' + let typedAt = 0 + const capture = () => { + const focused = $player.ownerDocument.activeElement as HTMLElement | null + origin = focused && $player.contains(focused) ? resolveFocusOrigin(focused) : $player + setOverlayOrigin($contextmenu, origin) + } + const targets = () => Array.from($contextmenu.querySelectorAll('[tabindex],button,input,select,textarea,a[href],[contenteditable]')) + .filter(element => element.tabIndex >= 0 && available(element)) + const label = art.i18n.get('Context Menu') + if (!active()) + return { pointer: () => false } + $contextmenu.setAttribute('role', 'group') + $contextmenu.setAttribute('aria-label', label) + const changed = (show: boolean) => { + if (!active()) + return + if (show) { + if (!$contextmenu.contains($player.ownerDocument.activeElement)) + capture() + return + } + const focused = $player.ownerDocument.activeElement + const restore = $contextmenu.contains(focused) || (hadFocus && focused === $player.ownerDocument.body) + const previous = origin + origin = undefined + hadFocus = false + prefix = '' + setOverlayOrigin($contextmenu) + if (!restore) + return + if (previous && $player.contains(previous) && available(previous)) + previous.focus({ preventScroll: true }) + if ($player.ownerDocument.activeElement === $player.ownerDocument.body || $contextmenu.contains($player.ownerDocument.activeElement)) + focusPlayer(art) + } + art.on('contextmenu', changed) + scope.add(() => { + art.off('contextmenu', changed) + setOverlayOrigin($contextmenu) + }) + listen(scope, $contextmenu, 'focusin', () => { + hadFocus = true + }) + let pending = false + listen(scope, $contextmenu, 'focusout', (input) => { + if ($contextmenu.contains((input as FocusEvent).relatedTarget as Node | null) || pending) + return + pending = true + timeout(scope, () => { + pending = false + if (active() && menu.show && !$contextmenu.contains($player.ownerDocument.activeElement)) + menu.show = false + }, 0) + }) + listen(scope, $player, 'keydown', (input) => { + const event = input as KeyboardEvent + if (!active() || !plainKey(event) || event.defaultPrevented) + return + const opening = event.key === 'ContextMenu' || (event.key === 'F10' && event.shiftKey) + if (opening && art.constructor.CONTEXTMENU && !editable(event.target)) { + claimKey(event) + capture() + const rect = (event.target as HTMLElement).getBoundingClientRect() + open(rect.left, rect.bottom) + if (active() && menu.show) + targets()[0]?.focus({ preventScroll: true }) + return + } + if (!menu.show || !$contextmenu.contains(event.target as Node | null)) + return + if (event.key === 'Escape') { + claimKey(event) + menu.show = false + return + } + if (event.key === 'Tab') { + menu.show = false + return + } + if (editable(event.target)) + return + const items = targets() + const index = items.indexOf(event.target as HTMLElement) + let target: HTMLElement | undefined + if (event.key === 'ArrowDown' || event.key === 'ArrowRight') { + target = items[(index + 1) % items.length] + } + else if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') { + target = items[(index + items.length - 1) % items.length] + } + else if (event.key === 'Home') { + target = items[0] + } + else if (event.key === 'End') { + target = items[items.length - 1] + } + else if (event.key.length === 1 && event.key !== ' ') { + const key = event.key.toLowerCase() + prefix = Date.now() - typedAt > 700 ? key : prefix + key + typedAt = Date.now() + const search = [...prefix].every(letter => letter === key) ? key : prefix + target = [...items.slice(index + 1), ...items.slice(0, index + 1)].find(item => (item.getAttribute('aria-label') || item.textContent || '').trim().toLowerCase().startsWith(search)) + } + else { + return + } + claimKey(event) + target?.focus({ preventScroll: true }) + }) + return { + pointer(event: MouseEvent): boolean { + if (!active() || !art.constructor.CONTEXTMENU || editable(event.target)) + return false + capture() + return true + }, + } +} diff --git a/packages/artplayer/src/contextmenu/playbackRate.ts b/packages/artplayer/src/contextmenu/playbackRate.ts index e45191314..227099177 100644 --- a/packages/artplayer/src/contextmenu/playbackRate.ts +++ b/packages/artplayer/src/contextmenu/playbackRate.ts @@ -1,6 +1,7 @@ import type { ContextmenuFactory, ContextmenuOption } from './types' import { controlEvents } from '../control/resources' import { inverseClass, query } from '../utils' +import { keyboardChoices, updateChoices } from './choices' export default function playbackRate(option: ContextmenuOption): ContextmenuFactory { return (art) => { @@ -12,10 +13,11 @@ export default function playbackRate(option: ContextmenuOption): ContextmenuFact const html = PLAYBACK_RATE.map( item => `${item === 1 ? i18n.get('Normal') : item.toFixed(1)}`, ).join('') + const label = i18n.get('Play Speed') return { ...option, - html: `${i18n.get('Play Speed')}: ${html}`, + html: `${label}: ${html}`, click: (contextmenu, event) => { const value = event.target instanceof HTMLElement ? event.target.dataset.value : undefined if (value) { @@ -28,12 +30,14 @@ export default function playbackRate(option: ContextmenuOption): ContextmenuFact const $default = query('[data-value="1"]', $panel) if ($default) inverseClass($default, 'art-current') + keyboardChoices($panel, label) on('video:ratechange', () => { const $current = Array.from($panel.querySelectorAll('span')).find( item => Number(item.dataset.value) === art.playbackRate, ) if ($current) { inverseClass($current, 'art-current') + updateChoices($panel) } }) }, diff --git a/packages/artplayer/src/contextmenu/position.ts b/packages/artplayer/src/contextmenu/position.ts new file mode 100644 index 000000000..a532fbc64 --- /dev/null +++ b/packages/artplayer/src/contextmenu/position.ts @@ -0,0 +1,17 @@ +import type { ContextmenuHost } from './types' +import { isClosing } from '../lifecycle/instance' +import { getRect, setStyles } from '../utils' + +export function positionContextmenu(art: ContextmenuHost, mouseX: number, mouseY: number): void { + const { $player, $contextmenu } = art.template + const { height: cHeight, width: cWidth, left: cLeft, top: cTop } = getRect($player) + const { height: mHeight, width: mWidth } = getRect($contextmenu) + let menuLeft = mouseX - cLeft + let menuTop = mouseY - cTop + if (mouseX + mWidth > cLeft + cWidth) + menuLeft = cWidth - mWidth + if (mouseY + mHeight > cTop + cHeight) + menuTop = cHeight - mHeight + if (!isClosing(art)) + setStyles($contextmenu, { top: `${menuTop}px`, left: `${menuLeft}px` }) +} diff --git a/packages/artplayer/src/control/airplay.ts b/packages/artplayer/src/control/airplay.ts index 52e5e49fe..857e828e8 100644 --- a/packages/artplayer/src/control/airplay.ts +++ b/packages/artplayer/src/control/airplay.ts @@ -1,5 +1,7 @@ import type { ControlFactory, ControlOption } from './types' +import { keyboardButton } from '../accessibility/button' import { appendElement } from '../component/dom' +import { entryScope } from '../component/resources' import { controlEvents } from './resources' export default function airplay(option: ControlOption): ControlFactory { @@ -9,6 +11,7 @@ export default function airplay(option: ControlOption): ControlFactory { mounted: ($control) => { const { proxy } = controlEvents(art, $control) const { icons } = art + keyboardButton(entryScope($control), $control) appendElement($control, icons.airplay) proxy($control, 'click', () => art.airplay()) }, diff --git a/packages/artplayer/src/control/fullscreen.ts b/packages/artplayer/src/control/fullscreen.ts index 3134ae8eb..37ccd6e74 100644 --- a/packages/artplayer/src/control/fullscreen.ts +++ b/packages/artplayer/src/control/fullscreen.ts @@ -1,5 +1,7 @@ import type { ControlFactory, ControlOption } from './types' +import { keyboardButton } from '../accessibility/button' import { appendElement } from '../component/dom' +import { entryScope } from '../component/resources' import { setStyle, tooltip } from '../utils' import { controlEvents } from './resources' @@ -10,6 +12,7 @@ export default function fullscreen(option: ControlOption): ControlFactory { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control) const { icons, i18n } = art + keyboardButton(entryScope($control), $control) const $fullscreenOn = appendElement($control, icons.fullscreenOn) const $fullscreenOff = appendElement($control, icons.fullscreenOff) diff --git a/packages/artplayer/src/control/fullscreenWeb.ts b/packages/artplayer/src/control/fullscreenWeb.ts index 65b6a4e91..eb12fcfa6 100644 --- a/packages/artplayer/src/control/fullscreenWeb.ts +++ b/packages/artplayer/src/control/fullscreenWeb.ts @@ -1,5 +1,7 @@ import type { ControlFactory, ControlOption } from './types' +import { keyboardButton } from '../accessibility/button' import { appendElement } from '../component/dom' +import { entryScope } from '../component/resources' import { setStyle, tooltip } from '../utils' import { controlEvents } from './resources' @@ -10,6 +12,7 @@ export default function fullscreenWeb(option: ControlOption): ControlFactory { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control) const { icons, i18n } = art + keyboardButton(entryScope($control), $control) const $fullscreenWebOn = appendElement($control, icons.fullscreenWebOn) const $fullscreenWebOff = appendElement($control, icons.fullscreenWebOff) diff --git a/packages/artplayer/src/control/index.ts b/packages/artplayer/src/control/index.ts index e602b06df..01f9995a0 100644 --- a/packages/artplayer/src/control/index.ts +++ b/packages/artplayer/src/control/index.ts @@ -1,5 +1,6 @@ import type { EntryInput, EntryOption, EventCleanup, SelectorItem } from '../component/types' import type { ControlHost } from './types' +import { focusVisibility } from '../accessibility/focus' import { ownEntry } from '../component/resources' import { getScope, isClosing } from '../lifecycle/instance' import { @@ -30,8 +31,22 @@ export default class Control extends Component { const { constructor } = art const { $player, $bottom } = this.art.template - ownEntry(art, $bottom) - const { on } = controlEvents(art, $bottom) + const scope = ownEntry(art, $bottom) + const keyboardFocused = focusVisibility(scope, $player, () => { + this.show = true + }) + const { on, proxy } = controlEvents(art, $bottom) + + proxy($player, 'focusin', (event) => { + art.isFocus = true + art.isInput = (event.target as Element | null)?.tagName === 'INPUT' + }) + proxy($player, 'focusout', (event) => { + if (!$player.contains(event.relatedTarget as Node | null)) { + art.isFocus = false + art.isInput = false + } + }) on('mousemove', () => { if (!isMobile) { @@ -57,6 +72,7 @@ export default class Control extends Component { !art.setting.show && !this.isHover && !art.isInput + && !keyboardFocused() && art.playing && this.show && Date.now() - this.timer >= constructor.CONTROL_HIDE_TIME diff --git a/packages/artplayer/src/control/pip.ts b/packages/artplayer/src/control/pip.ts index 43f783b2e..1d7b2cf95 100644 --- a/packages/artplayer/src/control/pip.ts +++ b/packages/artplayer/src/control/pip.ts @@ -1,5 +1,7 @@ import type { ControlFactory, ControlOption } from './types' +import { keyboardButton } from '../accessibility/button' import { appendElement } from '../component/dom' +import { entryScope } from '../component/resources' import { tooltip } from '../utils' import { controlEvents } from './resources' @@ -10,6 +12,7 @@ export default function pip(option: ControlOption): ControlFactory { mounted: ($control) => { const { on, proxy } = controlEvents(art, $control) const { icons, i18n } = art + keyboardButton(entryScope($control), $control) appendElement($control, icons.pip) diff --git a/packages/artplayer/src/control/playAndPause.ts b/packages/artplayer/src/control/playAndPause.ts index 095ec251d..ecb604dea 100644 --- a/packages/artplayer/src/control/playAndPause.ts +++ b/packages/artplayer/src/control/playAndPause.ts @@ -1,5 +1,7 @@ import type { ControlFactory, ControlOption } from './types' +import { keyboardButton } from '../accessibility/button' import { appendElement } from '../component/dom' +import { entryScope } from '../component/resources' import { setStyle, silencePromise, tooltip } from '../utils' import { controlEvents } from './resources' @@ -12,6 +14,7 @@ export default function playAndPause(option: ControlOption): ControlFactory { const $play = appendElement($control, icons.play) const $pause = appendElement($control, icons.pause) + keyboardButton(entryScope($control), $control, () => (art.playing ? $pause : $play).click()) tooltip($play, i18n.get('Play')) tooltip($pause, i18n.get('Pause')) @@ -24,11 +27,13 @@ export default function playAndPause(option: ControlOption): ControlFactory { }) function showPlay() { + $control.setAttribute('aria-label', i18n.get('Play')) setStyle($play, 'display', 'flex') setStyle($pause, 'display', 'none') } function showPause() { + $control.setAttribute('aria-label', i18n.get('Pause')) setStyle($play, 'display', 'none') setStyle($pause, 'display', 'flex') } diff --git a/packages/artplayer/src/control/progress.ts b/packages/artplayer/src/control/progress.ts index d0d69b495..ca0f52f5a 100644 --- a/packages/artplayer/src/control/progress.ts +++ b/packages/artplayer/src/control/progress.ts @@ -1,5 +1,6 @@ import type { ControlFactory, ControlOption } from './types' import { installProgressInteractions } from './progress/interactions' +import { installProgressKeyboard } from './progress/keyboard' import { mountProgressView } from './progress/view' export { getPosFromEvent, setCurrentTime } from './progress/position' @@ -20,6 +21,7 @@ export default function progress(options: ControlOption): ControlFactory { mounted: ($control) => { mountProgressView(art, $control) installProgressInteractions(art, $control) + installProgressKeyboard(art, $control) }, }) } diff --git a/packages/artplayer/src/control/progress/keyboard.ts b/packages/artplayer/src/control/progress/keyboard.ts new file mode 100644 index 000000000..48befbe96 --- /dev/null +++ b/packages/artplayer/src/control/progress/keyboard.ts @@ -0,0 +1,77 @@ +import type { ControlHost } from '../types' +import type ResourceScope from '../../lifecycle/scope' +import { keyboardSlider } from '../../accessibility/slider' +import { entryScope } from '../../component/resources' +import { isClosing } from '../../lifecycle/instance' +import { captureSource, getSourceScope } from '../../source/operation' +import { positionRestoration } from '../../source/restore-position' +import { secondToTime } from '../../utils' +import { controlEvents } from '../resources' + +export function installProgressKeyboard(art: ControlHost, element: HTMLDivElement): void { + const scope = entryScope(element) + const { on } = controlEvents(art, element) + let revision = 0 + let pending: ResourceScope | undefined + const update = keyboardSlider(scope, element, art.i18n.get('Progress'), () => ({ + min: 0, + max: art.duration, + value: art.currentTime, + step: art.constructor.SEEK_STEP, + text: value => `${secondToTime(value)} / ${secondToTime(Number.isFinite(art.duration) && art.duration > 0 ? art.duration : 0)}`, + }), (value) => { + const action = ++revision + pending?.dispose() + const operation = scope.child() + pending = operation + const releaseSource = getSourceScope(art).add(() => { + operation.dispose() + }) + operation.add(() => { + releaseSource() + }) + operation.add(() => { + if (pending === operation) + pending = undefined + }) + const sourceActive = captureSource(art) + const active = () => action === revision && !operation.closed && !isClosing(art) && sourceActive() + const position = positionRestoration(art, value, active) + const settle = () => { + if (!active()) { + operation.dispose() + return + } + if (position.ready()) { + operation.dispose() + update() + } + } + for (const name of ['video:seeked', 'video:ended'] as const) { + art.on(name, settle) + operation.add(() => { + art.off(name, settle) + }) + } + try { + art.emit('setBar', 'played', value / art.duration) + if (active()) { + position.restore(() => { + art.seek = value + }) + } + settle() + } + catch (error) { + operation.dispose() + throw error + } + }) + on('video:loadedmetadata', update) + on('video:durationchange', update) + on('video:emptied', update) + on('video:timeupdate', update) + on('video:seeking', update) + on('video:seeked', update) + on('video:ended', update) +} diff --git a/packages/artplayer/src/control/screenshot.ts b/packages/artplayer/src/control/screenshot.ts index 04bfb7f52..1baebd09d 100644 --- a/packages/artplayer/src/control/screenshot.ts +++ b/packages/artplayer/src/control/screenshot.ts @@ -1,5 +1,7 @@ import type { ControlFactory, ControlOption } from './types' +import { keyboardButton } from '../accessibility/button' import { appendElement } from '../component/dom' +import { entryScope } from '../component/resources' import { silencePromise } from '../utils' import { controlEvents } from './resources' @@ -10,6 +12,7 @@ export default function screenshot(option: ControlOption): ControlFactory { mounted: ($control) => { const { proxy } = controlEvents(art, $control) const { icons } = art + keyboardButton(entryScope($control), $control) appendElement($control, icons.screenshot) proxy($control, 'click', () => { diff --git a/packages/artplayer/src/control/selector-keyboard.ts b/packages/artplayer/src/control/selector-keyboard.ts new file mode 100644 index 000000000..9c4b4814a --- /dev/null +++ b/packages/artplayer/src/control/selector-keyboard.ts @@ -0,0 +1,191 @@ +import type ResourceScope from '../lifecycle/scope' +import { keyboardButton } from '../accessibility/button' +import { claimKey, plainKey } from '../accessibility/keyboard' +import { listen } from '../lifecycle/resources' + +const interactive = 'button,input,select,textarea,a[href],[tabindex],[contenteditable]' + +export function selectorKeyboard(scope: ResourceScope, owner: HTMLElement, value: HTMLElement, list: HTMLElement, label: string): (restore?: boolean) => void { + if (scope.closed) + return () => {} + const items = Array.from(list.children) as HTMLElement[] + const complex = items.some(item => item.querySelector(interactive)) + list.setAttribute('role', complex ? 'group' : 'listbox') + list.setAttribute('aria-label', label) + let hovered = false + let opened = false + let dismissed = false + let prefix = '' + let typedAt = 0 + const expanded = () => items.length > 0 && (opened || (hovered && !dismissed)) + const trigger = () => value.querySelector('button,a[href],[role="button"]') || value + const refresh = (restore = false) => { + if (scope.closed) + return + const target = trigger() + if (value.querySelector(interactive)) { + value.removeAttribute('role') + value.removeAttribute('tabindex') + } + else { + value.setAttribute('role', 'button') + value.tabIndex = 0 + } + if (target !== value) { + value.removeAttribute('aria-haspopup') + value.removeAttribute('aria-expanded') + value.removeAttribute('aria-disabled') + } + if (complex) + target.removeAttribute('aria-haspopup') + else + target.setAttribute('aria-haspopup', 'listbox') + target.setAttribute('aria-expanded', String(expanded())) + target.setAttribute('aria-disabled', String(items.length === 0)) + if (restore && value.isConnected && value.ownerDocument.activeElement === value.ownerDocument.body) + target.focus({ preventScroll: true }) + } + const visibility = (state: boolean, hide = false) => { + opened = state + dismissed = hide + owner.classList.toggle('art-selector-open', state) + owner.classList.toggle('art-selector-dismissed', hide) + refresh() + } + const focus = (item?: HTMLElement) => { + if (!item || scope.closed) + return + const target = item.querySelector(interactive) || item + target.focus({ preventScroll: true }) + if (!scope.closed) + item.scrollIntoView({ block: 'nearest', inline: 'nearest' }) + } + const open = (last = false) => { + if (scope.closed || !items.length) + return + visibility(true) + prefix = '' + focus(items.find(item => item.classList.contains('art-current')) || items[last ? items.length - 1 : 0]) + } + const close = () => { + if (scope.closed) + return + const restore = list.contains(owner.ownerDocument.activeElement) + visibility(false, true) + prefix = '' + if (restore && value.isConnected) + trigger().focus({ preventScroll: true }) + } + keyboardButton(scope, value, () => { + value.click() + if (owner.ownerDocument.activeElement === value) + open() + }) + refresh() + for (const item of items) { + const selected = item.classList.contains('art-current') + if (!complex) { + item.setAttribute('role', 'option') + item.setAttribute('aria-selected', String(selected)) + } + else { + item.setAttribute('aria-current', String(selected)) + } + if (!item.querySelector(interactive)) { + item.tabIndex = -1 + keyboardButton(scope, item, () => { + item.click() + close() + }) + } + } + listen(scope, value, 'keydown', (input) => { + const event = input as KeyboardEvent + if (!plainKey(event) || event.defaultPrevented || (event.target !== value && event.target !== trigger())) + return + if (event.key === 'ArrowDown' || event.key === 'ArrowUp') { + claimKey(event) + open(event.key === 'ArrowUp') + } + else if (event.key === 'Escape' && expanded()) { + claimKey(event) + close() + } + }) + listen(scope, value, 'click', (event) => { + if (event.isTrusted && (event as MouseEvent).detail === 0 && trigger() !== value) + open() + }) + listen(scope, list, 'keydown', (input) => { + const event = input as KeyboardEvent + if (!plainKey(event) || event.defaultPrevented) + return + if (event.key === 'Escape') { + claimKey(event) + close() + return + } + const index = items.indexOf(event.target as HTMLElement) + if (index < 0) + return + if (event.key.length !== 1) + prefix = '' + let next: number | undefined + switch (event.key) { + case 'ArrowDown': + next = Math.min(index + 1, items.length - 1) + break + case 'ArrowUp': + next = Math.max(index - 1, 0) + break + case 'Home': + next = 0 + break + case 'End': + next = items.length - 1 + break + case 'ArrowLeft': + case 'ArrowRight': + claimKey(event) + return + default: { + if (event.key.length !== 1 || event.key === ' ') + return + const now = Date.now() + prefix = now - typedAt < 500 ? prefix + event.key.toLocaleLowerCase() : event.key.toLocaleLowerCase() + typedAt = now + const query = [...prefix].every(char => char === prefix[0]) ? prefix[0]! : prefix + for (let offset = 1; offset <= items.length; offset++) { + const candidate = (index + offset) % items.length + if (items[candidate]!.textContent?.trim().toLocaleLowerCase().startsWith(query)) { + next = candidate + break + } + } + } + } + claimKey(event) + if (next !== undefined) + focus(items[next]) + }) + listen(scope, list, 'click', (event) => { + if (event.isTrusted && (event as MouseEvent).detail === 0) + close() + }) + listen(scope, owner, 'mouseenter', () => { + hovered = true + visibility(opened) + }) + listen(scope, owner, 'mouseleave', () => { + hovered = false + visibility(list.contains(owner.ownerDocument.activeElement)) + }) + listen(scope, owner, 'focusout', (event) => { + if (!owner.contains((event as FocusEvent).relatedTarget as Node | null)) + visibility(false, true) + }) + scope.add(() => { + owner.classList.remove('art-selector-open', 'art-selector-dismissed') + }) + return refresh +} diff --git a/packages/artplayer/src/control/selector.ts b/packages/artplayer/src/control/selector.ts index e99d0cf04..3d0bc98c2 100644 --- a/packages/artplayer/src/control/selector.ts +++ b/packages/artplayer/src/control/selector.ts @@ -4,12 +4,14 @@ import { appendElement } from '../component/dom' import { entryScope } from '../component/resources' import { trackSelection } from '../component/selection' import { addClass, append, def, errorHandle, getComposedPath, inverseClass } from '../utils' +import { selectorKeyboard } from './selector-keyboard' interface Binding { option: EntryOption item: HTMLDivElement value: HTMLDivElement owner: HTMLDivElement + refresh?: (restore?: boolean) => void } const bindings = new WeakMap() @@ -32,13 +34,17 @@ function setHTML(element: HTMLElement, value: unknown): void { export function checkSelector(target?: SelectorItem): void { if (!target) return + const restore = target.$control_value!.contains(target.$control_value!.ownerDocument.activeElement) setHTML(target.$control_value!, target.html) for (let index = 0; index < target.$control_option!.length; index++) { const item = target.$control_option![index]! item.default = item === target + const element = item.$control_item! + element.setAttribute(element.getAttribute('role') === 'option' ? 'aria-selected' : 'aria-current', String(item.default)) if (item.default) inverseClass(item.$control_item!, 'art-current') } + bindings.get(target)?.refresh?.(restore) } export function renderSelector(art: ControlHost, check: (target?: SelectorItem) => void, option: EntryOption, $ref: HTMLDivElement, events: EventCleanup[]): void { @@ -81,8 +87,11 @@ export function renderSelector(art: ControlHost, check: (target?: SelectorItem) return if (option.onSelect) { const value = await option.onSelect.call(art, item, item.$control_item!, event) - if (active()) + if (active()) { + const restore = $value.contains($value.ownerDocument.activeElement) setHTML($value, value) + bindings.get(item)?.refresh?.(restore) + } } } catch (error) { @@ -93,4 +102,7 @@ export function renderSelector(art: ControlHost, check: (target?: SelectorItem) } }) events.push(event) + const refresh = selectorKeyboard(scope, $ref, $value, $list, String(option.tooltip || option.name || $value.textContent || art.i18n.get('Open'))) + for (const item of selector) + bindings.get(item)!.refresh = refresh } diff --git a/packages/artplayer/src/control/setting.ts b/packages/artplayer/src/control/setting.ts index 180a9c857..ab73fdb8a 100644 --- a/packages/artplayer/src/control/setting.ts +++ b/packages/artplayer/src/control/setting.ts @@ -1,5 +1,7 @@ import type { ControlFactory, ControlOption } from './types' +import { keyboardButton } from '../accessibility/button' import { appendElement } from '../component/dom' +import { entryScope } from '../component/resources' import { tooltip } from '../utils' import { controlEvents } from './resources' @@ -12,6 +14,8 @@ export default function setting(option: ControlOption): ControlFactory { const { icons, i18n } = art appendElement($control, icons.setting) + keyboardButton(entryScope($control), $control) + $control.setAttribute('aria-expanded', 'false') proxy($control, 'click', () => { art.setting.toggle() @@ -19,6 +23,7 @@ export default function setting(option: ControlOption): ControlFactory { }) on('setting', (value) => { + $control.setAttribute('aria-expanded', String(value)) tooltip($control, i18n.get(value ? 'Hide Setting' : 'Show Setting')) }) }, diff --git a/packages/artplayer/src/control/types.ts b/packages/artplayer/src/control/types.ts index b1761d98c..8196e596d 100644 --- a/packages/artplayer/src/control/types.ts +++ b/packages/artplayer/src/control/types.ts @@ -9,6 +9,10 @@ export interface UIEvents { 'document:mouseup': [MouseEvent] 'video:timeupdate': [Event] 'video:loadedmetadata': [Event] + 'video:durationchange': [Event] + 'video:emptied': [Event] + 'video:seeking': [Event] + 'video:seeked': [Event] 'video:progress': [Event] 'video:ended': [Event] 'video:playing': [Event] @@ -22,6 +26,7 @@ export interface UIEvents { 'fullscreenWeb': [boolean] 'pip': [boolean] 'setting': [boolean] + 'contextmenu': [boolean] 'aspectRatio': [string] 'flip': [string] 'blur': [Event] @@ -34,6 +39,7 @@ type IconName = 'play' | 'pause' | 'volume' | 'volumeClose' | 'fullscreenOn' | ' export interface ControlHost extends ComponentHost, SubscriptionHost, PipProperty { template: { + $video?: { readonly currentTime: number, readonly seeking?: boolean } $player: HTMLDivElement $bottom: HTMLDivElement $controls: HTMLDivElement @@ -55,9 +61,10 @@ export interface ControlHost extends ComponentHost, SubscriptionHost, } icons: Record & { indicator?: HTMLElement } i18n: { get: (key: string) => string } - constructor: { CONTROL_HIDE_TIME: number, USE_RAF: boolean } + constructor: { CONTROL_HIDE_TIME: number, USE_RAF: boolean, SEEK_STEP: number, VOLUME_STEP: number } setting: { show: boolean, toggle: () => void, resize: () => void } isInput: boolean + isFocus: boolean isRotate: boolean playing: boolean muted: boolean diff --git a/packages/artplayer/src/control/volume.ts b/packages/artplayer/src/control/volume.ts index 972328e0c..4bce280f6 100644 --- a/packages/artplayer/src/control/volume.ts +++ b/packages/artplayer/src/control/volume.ts @@ -1,5 +1,9 @@ import type { ControlFactory, ControlOption } from './types' +import { keyboardButton } from '../accessibility/button' +import { keyboardSlider } from '../accessibility/slider' import { appendElement } from '../component/dom' +import { entryScope } from '../component/resources' +import { isClosing } from '../lifecycle/instance' import { getRect, isMobile, setStyle } from '../utils' import { controlEvents } from './resources' @@ -8,10 +12,14 @@ export default function volume(option: ControlOption): ControlFactory { ...option, mounted: ($control) => { const { on, proxy } = controlEvents(art, $control) - const { icons } = art + const { icons, i18n } = art const $volume = appendElement($control, icons.volume) const $close = appendElement($control, icons.volumeClose) + for (const element of [$volume, $close]) { + keyboardButton(entryScope($control), element) + element.setAttribute('aria-label', i18n.get('Mute')) + } const $panel = appendElement($control, '
') const $inner = appendElement($panel, '
') const $value = appendElement($inner, `
`) @@ -19,6 +27,20 @@ export default function volume(option: ControlOption): ControlFactory { const $handle = appendElement($slider, `
`) const $loaded = appendElement($handle, `
`) const $indicator = appendElement($slider, `
`) + const scope = entryScope($control) + let revision = 0 + const updateSlider = keyboardSlider(scope, $slider, i18n.get('Volume'), () => ({ + min: 0, + max: 100, + value: art.muted ? 0 : art.volume * 100, + step: art.constructor.VOLUME_STEP * 100, + text: value => `${Math.round(value)}%`, + }), (value) => { + const action = ++revision + art.muted = false + if (action === revision && !scope.closed && !isClosing(art)) + art.volume = value / 100 + }, 'vertical') function getVolumeFromEvent(event: MouseEvent) { const { top, height } = getRect($slider) @@ -26,7 +48,13 @@ export default function volume(option: ControlOption): ControlFactory { } function update() { - if (art.muted || art.volume === 0) { + updateSlider() + const focused = $control.ownerDocument.activeElement + const muted = art.muted || art.volume === 0 + const visible = muted ? $close : $volume + $volume.setAttribute('aria-pressed', String(art.muted)) + $close.setAttribute('aria-pressed', String(art.muted)) + if (muted) { setStyle($volume, 'display', 'none') setStyle($close, 'display', 'flex') setStyle($indicator, 'top', '100%') @@ -41,6 +69,8 @@ export default function volume(option: ControlOption): ControlFactory { setStyle($loaded, 'top', `${100 - percentage}%`) $value.textContent = String(Math.floor(percentage)) } + if ((focused === $volume || focused === $close) && focused !== visible) + visible.focus({ preventScroll: true }) } update() diff --git a/packages/artplayer/src/display/mini-focus.ts b/packages/artplayer/src/display/mini-focus.ts new file mode 100644 index 000000000..97067c110 --- /dev/null +++ b/packages/artplayer/src/display/mini-focus.ts @@ -0,0 +1,36 @@ +import type { MiniHost } from './types' +import { resolveFocusOrigin } from '../accessibility/overlay-focus' +import { focusPlayer } from '../accessibility/player-focus' +import { isClosing } from '../lifecycle/instance' + +export function miniFocus(art: MiniHost) { + const player = art.template.$player + let origin: HTMLElement | undefined + return { + entering(): (focus?: () => void) => void { + const doc = player.ownerDocument + const focused = doc.activeElement as HTMLElement | null + const inside = focused && player.contains(focused) + if (!art.template.$mini?.contains(focused)) + origin = inside ? resolveFocusOrigin(focused) : undefined + const keyboard = inside && player.classList.contains('art-keyboard-focus') + return (focus) => { + if (keyboard && !isClosing(art) && (doc.activeElement === focused || doc.activeElement === doc.body)) + focus?.() + } + }, + leaving(popup?: HTMLElement): () => void { + const doc = player.ownerDocument + const inside = popup?.contains(doc.activeElement) + return () => { + if (!inside || isClosing(art) || (doc.activeElement !== doc.body && !popup?.contains(doc.activeElement))) + return + const visible = origin && doc.defaultView?.getComputedStyle(origin).visibility + if (origin?.isConnected && origin.getClientRects().length && visible !== 'hidden' && visible !== 'collapse' && origin.getAttribute('aria-disabled') !== 'true' && !origin.matches(':disabled') && !origin.closest('[inert]')) + origin.focus({ preventScroll: true }) + else + focusPlayer(art) + } + }, + } +} diff --git a/packages/artplayer/src/display/mini-view.ts b/packages/artplayer/src/display/mini-view.ts index 8d1ef01e5..ef2888c75 100644 --- a/packages/artplayer/src/display/mini-view.ts +++ b/packages/artplayer/src/display/mini-view.ts @@ -1,5 +1,8 @@ import type ResourceScope from '../lifecycle/scope' import type { MiniHost } from './types' +import { keyboardButton } from '../accessibility/button' +import { claimKey, plainKey } from '../accessibility/keyboard' +import { isClosing } from '../lifecycle/instance' import { listen } from '../lifecycle/resources' import { silencePromise } from '../utils/error' import { miniDrag } from './mini-drag' @@ -8,6 +11,7 @@ export interface MiniView { element: HTMLElement cancelDrag: () => void fresh: boolean + focus?: () => void } export function createMiniView(art: MiniHost, parent: ResourceScope, active: () => boolean, hide: () => void): MiniView | undefined { @@ -42,6 +46,24 @@ export function createMiniView(art: MiniHost, parent: ResourceScope, active: () return state.append(play, pause) element.append(close, state) + keyboardButton(scope, close, () => close.click(), active) + keyboardButton(scope, state, () => (art.playing ? pause : play).click(), active) + const closeLabel = art.i18n.get('Close') + if (scope.closed || isClosing(art)) + return + close.setAttribute('aria-label', closeLabel) + const groupLabel = art.i18n.get('Mini Player') + if (scope.closed || isClosing(art)) + return + element.setAttribute('role', 'group') + element.setAttribute('aria-label', groupLabel) + listen(scope, element, 'keydown', (input) => { + const event = input as KeyboardEvent + if (active() && plainKey(event) && !event.defaultPrevented && event.key === 'Escape') { + claimKey(event) + hide() + } + }) listen(scope, close, 'click', hide) listen(scope, play, 'click', () => { silencePromise(art.play()) @@ -52,6 +74,10 @@ export function createMiniView(art: MiniHost, parent: ResourceScope, active: () const update = () => { if (scope.closed) return + const label = art.i18n.get(art.playing ? 'Pause' : 'Play') + if (scope.closed || isClosing(art)) + return + state.setAttribute('aria-label', label) play.style.display = art.playing ? 'none' : 'flex' pause.style.display = art.playing ? 'flex' : 'none' } @@ -68,7 +94,7 @@ export function createMiniView(art: MiniHost, parent: ResourceScope, active: () art.template.$mini = element document.body.append(element) if (!scope.closed) - return { element, cancelDrag, fresh: true } + return { element, cancelDrag, fresh: true, focus: () => close.focus({ preventScroll: true }) } } catch (error) { scope.dispose() diff --git a/packages/artplayer/src/display/mini.ts b/packages/artplayer/src/display/mini.ts index 94dc00799..e702cb539 100644 --- a/packages/artplayer/src/display/mini.ts +++ b/packages/artplayer/src/display/mini.ts @@ -2,6 +2,7 @@ import type { MiniView } from './mini-view' import type { Placement } from './placement' import type { MiniHost } from './types' import { getScope, isClosing } from '../lifecycle/instance' +import { miniFocus } from './mini-focus' import { miniGeometry, miniPosition } from './mini-layout' import { createMiniView } from './mini-view' import { capturePlacement, restorePlacement } from './placement' @@ -15,6 +16,7 @@ export function mini(art: MiniHost): PropertyDescriptor { let creating = false let queued = false const active = () => !isClosing(art) && $player.classList.contains('art-mini') + const focus = miniFocus(art) function restore() { if (placement) { @@ -37,6 +39,7 @@ export function mini(art: MiniHost): PropertyDescriptor { return const current = ++revision queued = false + const restoreFocus = focus.leaving(art.template.$mini) restore() if (isClosing(art) || current !== revision) return @@ -44,7 +47,9 @@ export function mini(art: MiniHost): PropertyDescriptor { $player.classList.remove('art-mini') if (art.template.$mini) { art.template.$mini.style.display = 'none' - art.emit('mini', false) + restoreFocus() + if (!isClosing(art) && current === revision) + art.emit('mini', false) } } @@ -67,6 +72,7 @@ export function mini(art: MiniHost): PropertyDescriptor { queued = true return } + const enterFocus = focus.entering() art.state = 'mini' if (isClosing(art) || current !== revision) return @@ -115,6 +121,8 @@ export function mini(art: MiniHost): PropertyDescriptor { return art.storage.set('left', position.left) } + if (!isClosing(art) && current === revision) + enterFocus(view.focus) if (!isClosing(art) && current === revision) art.emit('mini', true) } diff --git a/packages/artplayer/src/display/types.ts b/packages/artplayer/src/display/types.ts index 89cce2a03..801e5fae9 100644 --- a/packages/artplayer/src/display/types.ts +++ b/packages/artplayer/src/display/types.ts @@ -57,6 +57,7 @@ export interface MiniEvents { export interface MiniHost extends SubscriptionHost { template: { $player: HTMLElement, $video: HTMLElement, $mini?: HTMLElement } + i18n: { get: (key: string) => string } icons: { close: HTMLElement, play: HTMLElement, pause: HTMLElement } storage: { get: (key: string) => unknown, set: (key: string, value: number) => unknown } state: string diff --git a/packages/artplayer/src/display/web-fullscreen.ts b/packages/artplayer/src/display/web-fullscreen.ts index b0e99cd4a..4820762c5 100644 --- a/packages/artplayer/src/display/web-fullscreen.ts +++ b/packages/artplayer/src/display/web-fullscreen.ts @@ -1,5 +1,6 @@ import type { Placement } from './placement' import type { WebFullscreenHost } from './types' +import { captureMovedFocus } from '../accessibility/moved-focus' import { getScope, isClosing } from '../lifecycle/instance' import { ResourceCleanupError } from '../lifecycle/scope' import { capturePlacement, restorePlacement } from './placement' @@ -55,6 +56,7 @@ export function webFullscreen(art: WebFullscreenHost): (value: boolean) => void return const current = ++revision const active = () => current === revision && !isClosing(art) + const restoreFocus = captureMovedFocus($player) if (value) { if (!saved) saved = { placement: capturePlacement($player), style: $player.getAttribute('style') } @@ -72,10 +74,15 @@ export function webFullscreen(art: WebFullscreenHost): (value: boolean) => void $player.classList.add('art-fullscreen-web') } catch (error) { - if (active() && restore(snapshot, active)) + if (active() && restore(snapshot, active)) { saved = undefined + restoreFocus() + } throw error } + if (!active()) + return + restoreFocus() if (!active()) return art.emit('fullscreenWeb', true) @@ -89,6 +96,9 @@ export function webFullscreen(art: WebFullscreenHost): (value: boolean) => void else { $player.classList.remove('art-fullscreen-web') } + if (!active()) + return + restoreFocus() if (!active()) return art.emit('fullscreenWeb', false) diff --git a/packages/artplayer/src/i18n/ar.ts b/packages/artplayer/src/i18n/ar.ts index e14d72c2f..8fbe49b62 100644 --- a/packages/artplayer/src/i18n/ar.ts +++ b/packages/artplayer/src/i18n/ar.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const ar = { + 'Context Menu': 'قائمة السياق', + 'Lock': 'قفل', + 'Back': 'رجوع', + 'Settings': 'الإعدادات', + 'Progress': 'تقدم التشغيل', 'Video Info': 'معلومات الفيديو', 'Close': 'إغلاق', 'Video Load Failed': 'فشل تحميل الفيديو', diff --git a/packages/artplayer/src/i18n/cs.ts b/packages/artplayer/src/i18n/cs.ts index 84a8301d3..2ae6a6e94 100644 --- a/packages/artplayer/src/i18n/cs.ts +++ b/packages/artplayer/src/i18n/cs.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const cs = { + 'Context Menu': 'Kontextová nabídka', + 'Lock': 'Zamknout', + 'Back': 'Zpět', + 'Settings': 'Nastavení', + 'Progress': 'Průběh přehrávání', 'Video Info': 'Info o videu', 'Close': 'Zavřít', 'Video Load Failed': 'Nahrání videa selhalo', diff --git a/packages/artplayer/src/i18n/es.ts b/packages/artplayer/src/i18n/es.ts index 76dd0341a..d5e3a2eaf 100644 --- a/packages/artplayer/src/i18n/es.ts +++ b/packages/artplayer/src/i18n/es.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const es = { + 'Context Menu': 'Menú contextual', + 'Lock': 'Bloquear', + 'Back': 'Volver', + 'Settings': 'Configuración', + 'Progress': 'Progreso de reproducción', 'Video Info': 'Información del video', 'Close': 'Cerrar', 'Video Load Failed': 'Falló carga de video', diff --git a/packages/artplayer/src/i18n/fa.ts b/packages/artplayer/src/i18n/fa.ts index ae1b61474..7ffddea98 100644 --- a/packages/artplayer/src/i18n/fa.ts +++ b/packages/artplayer/src/i18n/fa.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const fa = { + 'Context Menu': 'منوی زمینه', + 'Lock': 'قفل', + 'Back': 'بازگشت', + 'Settings': 'تنظیمات', + 'Progress': 'پیشرفت پخش', 'Video Info': 'اطلاعات ویدیو', 'Close': 'بستن', 'Video Load Failed': 'بارگذاری ناموفق', diff --git a/packages/artplayer/src/i18n/fr.ts b/packages/artplayer/src/i18n/fr.ts index 0d5a723fc..1de5877ea 100644 --- a/packages/artplayer/src/i18n/fr.ts +++ b/packages/artplayer/src/i18n/fr.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const fr = { + 'Context Menu': 'Menu contextuel', + 'Lock': 'Verrouiller', + 'Back': 'Retour', + 'Settings': 'Paramètres', + 'Progress': 'Progression de lecture', 'Video Info': 'Informations de la vidéo', 'Close': 'Fermer', 'Video Load Failed': 'Téléchargement de la vidéo échoué', diff --git a/packages/artplayer/src/i18n/id.ts b/packages/artplayer/src/i18n/id.ts index aadba4b1c..e5d508e45 100644 --- a/packages/artplayer/src/i18n/id.ts +++ b/packages/artplayer/src/i18n/id.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const id = { + 'Context Menu': 'Menu konteks', + 'Lock': 'Kunci', + 'Back': 'Kembali', + 'Settings': 'Pengaturan', + 'Progress': 'Progres pemutaran', 'Video Info': 'Informasi Video', 'Close': 'Tutup', 'Video Load Failed': 'Gagal Memuat Video', diff --git a/packages/artplayer/src/i18n/pl.ts b/packages/artplayer/src/i18n/pl.ts index 243df1aab..163012fc4 100644 --- a/packages/artplayer/src/i18n/pl.ts +++ b/packages/artplayer/src/i18n/pl.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const pl = { + 'Context Menu': 'Menu kontekstowe', + 'Lock': 'Zablokuj', + 'Back': 'Wstecz', + 'Settings': 'Ustawienia', + 'Progress': 'Postęp odtwarzania', 'Video Info': 'Informacje o wideo', 'Close': 'Zamknij', 'Video Load Failed': 'Błąd ładowania wideo', diff --git a/packages/artplayer/src/i18n/ru.ts b/packages/artplayer/src/i18n/ru.ts index 5ad63ea5d..d5e24ecf9 100644 --- a/packages/artplayer/src/i18n/ru.ts +++ b/packages/artplayer/src/i18n/ru.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const ru = { + 'Context Menu': 'Контекстное меню', + 'Lock': 'Заблокировать', + 'Back': 'Назад', + 'Settings': 'Настройки', + 'Progress': 'Ход воспроизведения', 'Video Info': 'Информация', 'Close': 'Закрыть', 'Video Load Failed': 'Ошибка загрузки видео', diff --git a/packages/artplayer/src/i18n/tr.ts b/packages/artplayer/src/i18n/tr.ts index b12a18580..eb4512701 100644 --- a/packages/artplayer/src/i18n/tr.ts +++ b/packages/artplayer/src/i18n/tr.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const tr = { + 'Context Menu': 'Bağlam menüsü', + 'Lock': 'Kilitle', + 'Back': 'Geri', + 'Settings': 'Ayarlar', + 'Progress': 'Oynatma ilerlemesi', 'Video Info': 'Video Bilgisi', 'Close': 'Kapat', 'Video Load Failed': 'Video Yüklenemedi', diff --git a/packages/artplayer/src/i18n/vi.ts b/packages/artplayer/src/i18n/vi.ts index 318684398..41cee8823 100644 --- a/packages/artplayer/src/i18n/vi.ts +++ b/packages/artplayer/src/i18n/vi.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const vi = { + 'Context Menu': 'Menu ngữ cảnh', + 'Lock': 'Khóa', + 'Back': 'Quay lại', + 'Settings': 'Cài đặt', + 'Progress': 'Tiến trình phát', 'Video Info': 'Thông tin video', 'Close': 'Đóng', 'Video Load Failed': 'Tải video thất bại', diff --git a/packages/artplayer/src/i18n/zh-cn.ts b/packages/artplayer/src/i18n/zh-cn.ts index 955eaa866..6359350ff 100644 --- a/packages/artplayer/src/i18n/zh-cn.ts +++ b/packages/artplayer/src/i18n/zh-cn.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const zhCn = { + 'Context Menu': '快捷菜单', + 'Lock': '锁定', + 'Back': '返回', + 'Settings': '设置', + 'Progress': '播放进度', 'Video Info': '统计信息', 'Close': '关闭', 'Video Load Failed': '加载失败', diff --git a/packages/artplayer/src/i18n/zh-tw.ts b/packages/artplayer/src/i18n/zh-tw.ts index 86ed6614c..a7c136569 100644 --- a/packages/artplayer/src/i18n/zh-tw.ts +++ b/packages/artplayer/src/i18n/zh-tw.ts @@ -2,6 +2,11 @@ import type { Dictionary } from './publish' import { publishLanguage } from './publish' const zhTw = { + 'Context Menu': '快捷選單', + 'Lock': '鎖定', + 'Back': '返回', + 'Settings': '設定', + 'Progress': '播放進度', 'Video Info': '統計訊息', 'Close': '關閉', 'Video Load Failed': '載入失敗', diff --git a/packages/artplayer/src/info/keyboard.ts b/packages/artplayer/src/info/keyboard.ts new file mode 100644 index 000000000..0abc9803c --- /dev/null +++ b/packages/artplayer/src/info/keyboard.ts @@ -0,0 +1,66 @@ +import type ResourceScope from '../lifecycle/scope' +import type { InfoHost } from './poll' +import { keyboardButton } from '../accessibility/button' +import { claimKey, plainKey } from '../accessibility/keyboard' +import { resolveFocusOrigin } from '../accessibility/overlay-focus' +import { focusPlayer } from '../accessibility/player-focus' +import { isClosing } from '../lifecycle/instance' +import { listen } from '../lifecycle/resources' + +const origins = new WeakMap() + +export function infoKeyboard(art: InfoHost, scope: ResourceScope, close: () => void): void { + const { $player, $info, $infoClose } = art.template + if (!$info) + return + const active = () => !scope.closed && !isClosing(art) + const visible = () => $player.classList.contains('art-info-show') + const closeLabel = art.i18n.get('Close') + if (!active()) + return + const groupLabel = art.i18n.get('Video Info') + if (!active()) + return + $infoClose.setAttribute('aria-label', closeLabel) + $info.setAttribute('role', 'group') + $info.setAttribute('aria-label', groupLabel) + keyboardButton(scope, $infoClose, () => $infoClose.click(), visible) + listen(scope, $info, 'keydown', (input) => { + const event = input as KeyboardEvent + if (active() && visible() && plainKey(event) && !event.defaultPrevented && event.key === 'Escape') { + claimKey(event) + close() + } + }) + const changed = (show: boolean) => { + if (!active()) + return + const doc = $player.ownerDocument + const focused = doc.activeElement as HTMLElement | null + if (show) { + if (!$info.contains(focused)) { + origins.delete(art) + if (focused && $player.contains(focused)) { + origins.set(art, resolveFocusOrigin(focused)) + if ($player.classList.contains('art-keyboard-focus')) + $infoClose.focus({ preventScroll: true }) + } + } + } + else { + const origin = origins.get(art) + origins.delete(art) + if (!$info.contains(focused)) + return + const visibility = origin && doc.defaultView?.getComputedStyle(origin).visibility + if (origin?.isConnected && $player.contains(origin) && origin.getClientRects().length && visibility !== 'hidden' && visibility !== 'collapse' && !origin.matches(':disabled') && !origin.closest('[inert]') && origin.getAttribute('aria-disabled') !== 'true') + origin.focus({ preventScroll: true }) + else + focusPlayer(art) + } + } + art.on('info', changed) + scope.add(() => { + art.off('info', changed) + }) +} diff --git a/packages/artplayer/src/info/poll.ts b/packages/artplayer/src/info/poll.ts index dd8345345..4d7023daa 100644 --- a/packages/artplayer/src/info/poll.ts +++ b/packages/artplayer/src/info/poll.ts @@ -3,9 +3,11 @@ import type { ComponentHost } from '../component/types' import type ResourceScope from '../lifecycle/scope' import { isClosing } from '../lifecycle/instance' import { timeout } from '../lifecycle/resources' +import { infoKeyboard } from './keyboard' -export interface InfoHost extends ComponentHost, SubscriptionHost<{ destroy: [] }> { - template: { $player: HTMLElement, $infoPanel: HTMLElement, $infoClose: HTMLElement, $video: object } +export interface InfoHost extends ComponentHost, SubscriptionHost<{ destroy: [], info: [boolean] }> { + template: { $player: HTMLElement, $info: HTMLElement | null, $infoPanel: HTMLElement, $infoClose: HTMLElement, $video: object } + i18n: { get: (key: string) => string } constructor: { INFO_LOOP_TIME: number } proxy: ComponentHost['events']['proxy'] } @@ -36,6 +38,7 @@ export function pollInfo(art: InfoHost, scope: ResourceScope, close: () => void) scope.add(() => { art.off('destroy', destroy) }) + infoKeyboard(art, scope, close) const loop = () => { try { for (const item of items) { diff --git a/packages/artplayer/src/input/keyboard-focus.ts b/packages/artplayer/src/input/keyboard-focus.ts index 91cf6b675..b9b76be48 100644 --- a/packages/artplayer/src/input/keyboard-focus.ts +++ b/packages/artplayer/src/input/keyboard-focus.ts @@ -1,3 +1,5 @@ +import { isClaimedKey } from '../accessibility/keyboard' + function asElement(target: EventTarget | null | undefined): HTMLElement | undefined { if (target && (target as Node).nodeType === 1) return target as HTMLElement @@ -16,7 +18,7 @@ function editable(target: HTMLElement): boolean { } export function acceptsHotkey(event: KeyboardEvent, fallback: Document): boolean { - if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.isComposing || event.keyCode === 229) + if (isClaimedKey(event) || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.isComposing || event.keyCode === 229) return false const doc = eventDocument(event, fallback) let active = asElement(doc.activeElement) @@ -26,5 +28,12 @@ export function acceptsHotkey(event: KeyboardEvent, fallback: Document): boolean return false // The composed path exposes an editable descendant behind a retargeted shadow host. const first = asElement(event.composedPath?.()[0]) || asElement(event.target) + const enter = event.key === 'Enter' || event.code === 'Enter' || event.code === 'NumpadEnter' + const activation = enter || event.key === ' ' || event.code === 'Space' + if (activation) { + const selector = `button,summary,[role="button"],[role="switch"]${enter ? ',a[href]' : ''}` + if (first?.closest?.(selector) || active?.closest?.(selector)) + return false + } return !first || !editable(first) } diff --git a/packages/artplayer/src/plugins/lock-keyboard.ts b/packages/artplayer/src/plugins/lock-keyboard.ts new file mode 100644 index 000000000..4e8b7039f --- /dev/null +++ b/packages/artplayer/src/plugins/lock-keyboard.ts @@ -0,0 +1,44 @@ +import type ResourceScope from '../lifecycle/scope' +import type { LockHost } from './lock' +import { keyboardButton } from '../accessibility/button' +import { claimKey, plainKey } from '../accessibility/keyboard' +import { suspendFocus } from '../accessibility/suspend-focus' +import { isClosing } from '../lifecycle/instance' +import { listen } from '../lifecycle/resources' + +export function lockKeyboard(art: LockHost, element: HTMLElement, scope: ResourceScope, locked: () => boolean): (state: boolean) => void { + let suspension: ResourceScope | undefined + const active = () => !scope.closed && !isClosing(art) + const label = art.i18n.get('Lock') + if (!active()) + return () => {} + element.setAttribute('aria-label', label) + keyboardButton(scope, element) + listen(scope, element, 'keydown', (input) => { + const event = input as KeyboardEvent + if (active() && locked() && plainKey(event) && !event.defaultPrevented && event.key === 'Escape') { + claimKey(event) + element.click() + } + }) + const update = (state: boolean) => { + if (!active()) + return + element.setAttribute('aria-pressed', String(state)) + if (state && !suspension) { + const { $player, $bottom } = art.template + const hiddenFocus = $bottom.contains($bottom.ownerDocument.activeElement) && $player.classList.contains('art-keyboard-focus') + suspension = scope.child() + suspendFocus(suspension, $bottom) + if (active() && hiddenFocus) + element.focus({ preventScroll: true }) + } + else if (!state && suspension) { + const previous = suspension + suspension = undefined + previous.dispose() + } + } + update(locked()) + return update +} diff --git a/packages/artplayer/src/plugins/lock.ts b/packages/artplayer/src/plugins/lock.ts index a99fb529b..7ad952c76 100644 --- a/packages/artplayer/src/plugins/lock.ts +++ b/packages/artplayer/src/plugins/lock.ts @@ -3,9 +3,11 @@ import { appendElement } from '../component/dom' import { entryScope, subscribeEntry } from '../component/resources' import { isClosing } from '../lifecycle/instance' import { addClass, hasClass, removeClass, setStyle } from '../utils' +import { lockKeyboard } from './lock-keyboard' export interface LockHost extends SubscriptionHost<{ lock: [boolean] }> { - template: { $player: HTMLElement } + template: { $player: HTMLElement, $bottom: HTMLElement } + i18n: { get: (key: string) => string } icons: { lock: string | Element, unlock: string | Element } isLock: boolean emit: (name: 'lock', state: boolean) => unknown @@ -57,7 +59,17 @@ export default function lock(art: LockHost): { name: string, state: boolean } { const $unlock = appendElement($el, icons.unlock) if (scope.closed || isClosing(art)) return - setStyle($lock, 'display', 'none') + const updateKeyboard = lockKeyboard(art, $el, scope, getState) + if (scope.closed || isClosing(art)) + return + if (getState()) { + setStyle($lock, 'display', 'inline-flex') + if (!scope.closed && !isClosing(art)) + setStyle($unlock, 'display', 'none') + } + else { + setStyle($lock, 'display', 'none') + } subscribeEntry<{ lock: [boolean] }, 'lock'>(art, $el, 'lock', (state) => { if (isClosing(art)) @@ -65,6 +77,8 @@ export default function lock(art: LockHost): { name: string, state: boolean } { setStyle($lock, 'display', state ? 'inline-flex' : 'none') if (!scope.closed && !isClosing(art)) setStyle($unlock, 'display', state ? 'none' : 'inline-flex') + if (!scope.closed && !isClosing(art)) + updateKeyboard(state) }) }, click() { diff --git a/packages/artplayer/src/setting/index.ts b/packages/artplayer/src/setting/index.ts index 85c9d2acf..b61cb69cd 100644 --- a/packages/artplayer/src/setting/index.ts +++ b/packages/artplayer/src/setting/index.ts @@ -6,6 +6,8 @@ import Component from '../utils/component' import aspectRatio from './aspectRatio' import { installSettingEvents } from './events' import flip from './flip' +import { installSettingKeyboard } from './keyboard' +import { captureSettingFocus } from './keyboard-focus' import { resizeSetting } from './layout' import { findItem, formatTree, registerTreeOwner, releaseTreeOwner, traverseTree } from './model' import playbackRate from './playbackRate' @@ -53,6 +55,7 @@ export default class Setting extends SettingBase implements SettingManager { installSettingEvents(this) } + installSettingKeyboard(this) } get builtin(): SettingItem[] { @@ -103,6 +106,7 @@ export default class Setting extends SettingBase implements SettingManager { } remove(name: string): void { + const restoreFocus = captureSettingFocus(this) const item = this.find(name)! errorHandle(item, `Can't find [${name}] in the [setting]`) this.traverse((item) => { @@ -126,6 +130,7 @@ export default class Setting extends SettingBase implements SettingManager { } if (failures.length) throw new ResourceCleanupError(failures) + restoreFocus() } update(target: SettingItem): SettingItem { diff --git a/packages/artplayer/src/setting/keyboard-focus.ts b/packages/artplayer/src/setting/keyboard-focus.ts new file mode 100644 index 000000000..3f7d82fd8 --- /dev/null +++ b/packages/artplayer/src/setting/keyboard-focus.ts @@ -0,0 +1,55 @@ +import type { SettingManager } from './types' +import { focusPlayer } from '../accessibility/player-focus' +import { isClosing } from '../lifecycle/instance' +import { settingScopeActive } from './activity' +import { settingPanelScope } from './panels' + +function available(element: HTMLElement): boolean { + const visibility = element.ownerDocument.defaultView?.getComputedStyle(element).visibility + return element.isConnected && !element.matches(':disabled') && !element.closest('[inert]') && element.getAttribute('aria-disabled') !== 'true' && element.getClientRects().length > 0 && visibility !== 'hidden' && visibility !== 'collapse' +} + +export function settingFocusTargets(panel: HTMLElement): HTMLElement[] { + return Array.from(panel.querySelectorAll('[tabindex="0"],button,input,select,textarea,a[href],[contenteditable]')) + .filter(element => element.getAttribute('tabindex') !== '-1' && available(element)) +} + +export function returnSettingFocus(setting: SettingManager): void { + const { art, $parent } = setting + const player = art.template.$player + const doc = $parent.ownerDocument + const button = art.controls.setting + if (isClosing(art) || !$parent.contains(doc.activeElement)) + return + if (button && player.contains(button) && available(button)) + button.focus({ preventScroll: true }) + if (doc.activeElement === doc.body || $parent.contains(doc.activeElement)) + focusPlayer(art) +} + +export function focusSettingPanel(setting: SettingManager, preferred?: HTMLElement, last = false): void { + if (!setting.show || isClosing(setting.art) || !setting.active) + return + const panel = setting.cache.get(setting.active) + if (!panel || !settingScopeActive(settingPanelScope(panel))) + return + const targets = settingFocusTargets(panel) + const selected = panel.querySelector('.art-setting-item.art-current') + const target = targets.find(element => preferred === element || preferred?.contains(element)) + || (last ? targets[targets.length - 1] : targets.find(element => selected?.contains(element)) || targets.find(element => !element.classList.contains('art-setting-item-back')) || targets[0]) + target?.focus({ preventScroll: true }) + if (!isClosing(setting.art)) + target?.scrollIntoView({ block: 'nearest', inline: 'nearest' }) +} + +export function captureSettingFocus(setting: SettingManager): (preferred?: HTMLElement) => void { + const doc = setting.$parent.ownerDocument + const focused = doc.activeElement as HTMLElement | null + const inside = setting.$parent.contains(focused) + return (preferred) => { + if (!inside || isClosing(setting.art)) + return + if (doc.activeElement === doc.body || (doc.activeElement === focused && !focused?.getClientRects().length)) + focusSettingPanel(setting, preferred) + } +} diff --git a/packages/artplayer/src/setting/keyboard-item.ts b/packages/artplayer/src/setting/keyboard-item.ts new file mode 100644 index 000000000..88df66850 --- /dev/null +++ b/packages/artplayer/src/setting/keyboard-item.ts @@ -0,0 +1,30 @@ +import type ResourceScope from '../lifecycle/scope' +import type { SettingKind } from './selection' +import type { SettingItem, SettingManager } from './types' +import { keyboardButton } from '../accessibility/button' +import { isClosing } from '../lifecycle/instance' +import { settingScopeActive } from './activity' + +export function nameSettingRange(item: SettingItem): void { + const input = item.$item?.querySelector('.art-setting-range') + if (input) + input.setAttribute('aria-label', item.$html?.textContent || '') +} + +export function settingItemKeyboard(setting: SettingManager, item: SettingItem, element: HTMLDivElement, kind: SettingKind, scope: ResourceScope): void { + if (kind === 'range') { + nameSettingRange(item) + return + } + if (element.querySelector('button,input,select,textarea,a[href],[tabindex],[contenteditable]')) + return + if (kind === 'switch') { + element.setAttribute('role', 'switch') + element.setAttribute('aria-checked', String(Boolean(item.switch))) + element.setAttribute('aria-disabled', String(!item.onSwitch)) + } + else if (kind === 'selector' && !item.selector?.length) { + element.setAttribute('aria-current', String(Boolean(item.default))) + } + keyboardButton(scope, element, () => element.click(), () => settingScopeActive(scope) && !isClosing(setting.art)) +} diff --git a/packages/artplayer/src/setting/keyboard.ts b/packages/artplayer/src/setting/keyboard.ts new file mode 100644 index 000000000..03615e2b4 --- /dev/null +++ b/packages/artplayer/src/setting/keyboard.ts @@ -0,0 +1,134 @@ +import type { SettingManager } from './types' +import { claimKey, plainKey } from '../accessibility/keyboard' +import { getScope, isClosing } from '../lifecycle/instance' +import { listen, timeout } from '../lifecycle/resources' +import { settingScopeActive } from './activity' +import { focusSettingPanel, returnSettingFocus, settingFocusTargets } from './keyboard-focus' +import { settingPanelScope } from './panels' +import { settingScope } from './resources' + +export function installSettingKeyboard(setting: SettingManager): void { + const { art } = setting + const scope = getScope(art).child() + if (scope.closed) + return + const doc = () => setting.$parent.ownerDocument + let enterLast = false + const close = () => { + setting.show = false + if (!scope.closed && !isClosing(art)) + setting.render() + } + const changed = (show: boolean) => { + if (scope.closed || isClosing(art)) + return + if (show) { + if (doc().activeElement === art.controls.setting && art.template.$player.classList.contains('art-keyboard-focus')) + focusSettingPanel(setting, undefined, enterLast) + } + else if (setting.$parent.contains(doc().activeElement)) { + returnSettingFocus(setting) + } + } + art.on('setting', changed) + scope.add(() => { + art.off('setting', changed) + }) + listen(scope, art.template.$player, 'keydown', (input) => { + const event = input as KeyboardEvent + if (!plainKey(event) || event.defaultPrevented || isClosing(art)) + return + const target = event.target as HTMLElement + if (target === art.controls.setting) { + if (event.key === 'ArrowDown' || event.key === 'ArrowUp') { + claimKey(event) + if (!setting.show) { + enterLast = event.key === 'ArrowUp' + try { + setting.show = true + } + finally { + enterLast = false + } + } + else { + focusSettingPanel(setting, undefined, event.key === 'ArrowUp') + } + } + else if (event.key === 'Escape' && setting.show) { + claimKey(event) + close() + } + return + } + if (!setting.show || !setting.$parent.contains(target)) + return + if (event.key === 'Escape') { + claimKey(event) + close() + return + } + const row = target.closest('.art-setting-item') + if (!row || (target !== row && !target.matches('button,a[href],[role="button"]'))) + return + const panel = setting.active && setting.cache.get(setting.active) + if (!panel) + return + const currentItem = setting.active?.find(item => item.$item === row) + if (!settingScopeActive(settingPanelScope(panel)) || (currentItem && !settingScopeActive(settingScope(currentItem)))) { + if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) + claimKey(event) + return + } + const targets = settingFocusTargets(panel) + const index = targets.indexOf(target) + if (index < 0) + return + let next: number | undefined + switch (event.key) { + case 'ArrowDown': + next = Math.min(index + 1, targets.length - 1) + break + case 'ArrowUp': + next = Math.max(index - 1, 0) + break + case 'Home': + next = 0 + break + case 'End': + next = targets.length - 1 + break + case 'ArrowLeft': { + const back = panel.querySelector('.art-setting-item-back') + claimKey(event) + back?.click() + return + } + case 'ArrowRight': { + claimKey(event) + if (currentItem?.selector?.length) + target.click() + return + } + default: + return + } + claimKey(event) + if (next !== undefined) + focusSettingPanel(setting, targets[next]) + }) + let pending = false + listen(scope, setting.$parent, 'focusout', (event) => { + const next = (event as FocusEvent).relatedTarget as Node | null + if (next && (setting.$parent.contains(next) || next === art.controls.setting)) + return + if (pending) + return + pending = true + timeout(scope, () => { + pending = false + if (!scope.closed && !isClosing(art) && setting.show && !setting.$parent.contains(doc().activeElement) && doc().activeElement !== art.controls.setting) + close() + }, 0) + }) +} diff --git a/packages/artplayer/src/setting/render.ts b/packages/artplayer/src/setting/render.ts index 7e8af35a9..ea5ba4371 100644 --- a/packages/artplayer/src/setting/render.ts +++ b/packages/artplayer/src/setting/render.ts @@ -1,11 +1,14 @@ import type { SettingKind } from './selection' import type { SettingItem, SettingManager, SettingRange } from './types' +import { keyboardButton } from '../accessibility/button' import { appendElement } from '../component/dom' import { isClosing } from '../lifecycle/instance' import { timeout } from '../lifecycle/resources' import { addClass, append, def, has, inverseClass, setStyle } from '../utils' import { settingScopeActive } from './activity' import { captureSettingItem, rememberSettingState } from './checkpoint' +import { captureSettingFocus } from './keyboard-focus' +import { nameSettingRange, settingItemKeyboard } from './keyboard-item' import { ownSettingPanel, releaseSettingPanel, settingPanelScope } from './panels' import { ownSettingItem, proxySetting, settingItemOwner } from './resources' import { bindSettingActions } from './selection' @@ -21,6 +24,8 @@ function bindContent(item: SettingItem, key: 'icon' | 'html' | 'tooltip', elemen set(value: unknown) { element.innerHTML = '' append(element, value) + if (key === 'html') + nameSettingRange(item) }, }) } @@ -46,6 +51,10 @@ export function createSettingHeader(setting: SettingManager, item: SettingItem): append($left, $icon) append($left, item.$parent!.html) proxySetting(setting.art, item.$parent!, $item, 'click', () => setting.render(item.$parents), settingPanelScope($panel)) + const scope = settingPanelScope($panel) + if (!$item.querySelector('button,input,select,textarea,a[href],[tabindex],[contenteditable]')) + keyboardButton(scope, $item, () => $item.click(), () => settingScopeActive(scope) && !isClosing(setting.art)) + $item.setAttribute('aria-label', `${setting.art.i18n.get('Back')}: ${$item.textContent?.trim() || ''}`) append($panel, $item) } @@ -177,6 +186,7 @@ export function createSettingItem(setting: SettingManager, item: SettingItem, is get: () => $switchValue, set(value) { $switchValue = value + $item.setAttribute('aria-checked', String(Boolean(value))) if (value) { setStyle($switchOff, 'display', 'none') setStyle($switchOn, 'display', null) @@ -258,6 +268,7 @@ export function createSettingItem(setting: SettingManager, item: SettingItem, is configurable: true, get: () => $item, }) + settingItemKeyboard(setting, item, $item, type, scope) if (isUpdate) { if (oldItem?.parentNode) @@ -298,6 +309,7 @@ export function createSettingItem(setting: SettingManager, item: SettingItem, is export function renderSetting(setting: SettingManager, option = setting.option): void { if (isClosing(setting.art)) return + const restoreFocus = captureSettingFocus(setting) const cached = setting.cache.get(option) if (cached && !settingScopeActive(settingPanelScope(cached))) return @@ -335,6 +347,8 @@ export function renderSetting(setting: SettingManager, option = setting.option): if (!current()) return addClass($panel, 'art-setting-panel') + $panel.setAttribute('role', 'group') + $panel.setAttribute('aria-label', option[0]?.$parent?.$html?.textContent || setting.art.i18n.get('Settings')) append(setting.$parent, $panel) inverseClass($panel, 'art-current') @@ -376,4 +390,6 @@ export function renderSetting(setting: SettingManager, option = setting.option): throw error } } + if (currentNavigation()) + restoreFocus(previous?.[0]?.$parent?.$item) } diff --git a/packages/artplayer/src/setting/selection.ts b/packages/artplayer/src/setting/selection.ts index a42542e4e..0193afff2 100644 --- a/packages/artplayer/src/setting/selection.ts +++ b/packages/artplayer/src/setting/selection.ts @@ -13,6 +13,8 @@ export function checkSetting(setting: SettingManager, target?: SettingItem | nul target.$parent.tooltip = target.html setting.traverse((item) => { item.default = item === target + if (item.$item) + item.$item.setAttribute('aria-current', String(item.default)) if (item.default && item.$item) inverseClass(item.$item, 'art-current') }, target.$option) diff --git a/packages/artplayer/src/setting/types.ts b/packages/artplayer/src/setting/types.ts index 52fd43ec7..76c005ac9 100644 --- a/packages/artplayer/src/setting/types.ts +++ b/packages/artplayer/src/setting/types.ts @@ -34,6 +34,7 @@ export interface SettingItem extends TreeItem { } export interface SettingEvents { + 'setting': [boolean] 'blur': [Event] 'focus': [event: Event] 'resize': [] diff --git a/packages/artplayer/src/setting/update.ts b/packages/artplayer/src/setting/update.ts index 29bf53d4c..24622801c 100644 --- a/packages/artplayer/src/setting/update.ts +++ b/packages/artplayer/src/setting/update.ts @@ -5,6 +5,7 @@ import captureTemplate from '../lifecycle/template-rollback' import { inverseClass } from '../utils/dom' import { pauseSettingScope } from './activity' import { captureSettingItem } from './checkpoint' +import { captureSettingFocus } from './keyboard-focus' import { releaseSettingPanel, settingPanelScope } from './panels' import { cancelSettingAdd } from './registration' import { suspendSettingItem } from './resources' @@ -112,6 +113,7 @@ export function updateSetting(setting: SettingManager, target: SettingItem): Set return item || target if (!item) return setting.add(target) + const restoreFocus = captureSettingFocus(setting) cancelSettingAdd(item) cancelSettingUpdate(item) const restoreItem = captureSettingItem(item) @@ -161,6 +163,7 @@ export function updateSetting(setting: SettingManager, target: SettingItem): Set } }, ]) + restoreFocus(element) } catch (error) { console.warn('ArtPlayer setting restore failed:', error) @@ -197,6 +200,7 @@ export function updateSetting(setting: SettingManager, target: SettingItem): Set pending.delete(affected) } tree.dispose() + restoreFocus(item.$item) return item } catch (error) { diff --git a/packages/artplayer/src/source/restore-position.ts b/packages/artplayer/src/source/restore-position.ts index b1cf89a02..084a8d61f 100644 --- a/packages/artplayer/src/source/restore-position.ts +++ b/packages/artplayer/src/source/restore-position.ts @@ -13,11 +13,13 @@ export function positionRestoration(art: Pick manual || positionRevision(art) !== revision const seeking = () => !!art.template?.$video?.seeking return { - restore(): void { + restore(write = () => { + art.currentTime = target + }): void { if (!active() || manualPosition()) return const previousRevision = positionRevision(art) - art.currentTime = target + write() revision = positionRevision(art) // Nested public writes supersede the restoration's own setter call. if (revision > previousRevision + 1) diff --git a/packages/artplayer/src/style/accessibility.less b/packages/artplayer/src/style/accessibility.less new file mode 100644 index 000000000..5e1b372fc --- /dev/null +++ b/packages/artplayer/src/style/accessibility.less @@ -0,0 +1,22 @@ +.art-video-player { + [tabindex]:focus-visible, + input:focus-visible, + button:focus-visible, + a:focus-visible { + outline: 2px solid currentColor; + outline-offset: -2px; + } + + &.art-keyboard-focus :focus { + outline: 2px solid currentColor; + outline-offset: -2px; + } + + &.art-keyboard-focus:not(.art-lock) .art-bottom { + opacity: 1; + .art-controls, + .art-progress { + transform: translateY(0); + } + } +} diff --git a/packages/artplayer/src/style/index.less b/packages/artplayer/src/style/index.less index 06e970a79..e19f7ed0d 100644 --- a/packages/artplayer/src/style/index.less +++ b/packages/artplayer/src/style/index.less @@ -28,3 +28,4 @@ @import './selector'; @import './hint'; @import './mobile'; +@import './accessibility'; diff --git a/packages/artplayer/src/style/mini.less b/packages/artplayer/src/style/mini.less index c6d62d8ff..aac867aed 100644 --- a/packages/artplayer/src/style/mini.less +++ b/packages/artplayer/src/style/mini.less @@ -56,10 +56,16 @@ opacity: 0.9; } - &:hover { + &:hover, + &:focus-within { .art-mini-close, .art-mini-state { opacity: 1; } } + + [role='button']:focus-visible { + outline: 2px solid #fff; + outline-offset: -2px; + } } diff --git a/packages/artplayer/src/style/plugins.less b/packages/artplayer/src/style/plugins.less index 85dd4bb36..cd0c92c90 100644 --- a/packages/artplayer/src/style/plugins.less +++ b/packages/artplayer/src/style/plugins.less @@ -41,6 +41,20 @@ } &.art-lock { + .art-layer-lock { + display: flex; + } + + &:not(.art-control-show) .art-layer-lock { + opacity: 0; + pointer-events: none; + + &:focus-within { + opacity: 1; + pointer-events: auto; + } + } + .art-subtitle { bottom: var(--art-subtitle-bottom) !important; } diff --git a/packages/artplayer/src/style/selector.less b/packages/artplayer/src/style/selector.less index effa96802..25c333538 100644 --- a/packages/artplayer/src/style/selector.less +++ b/packages/artplayer/src/style/selector.less @@ -13,12 +13,13 @@ overflow-y: auto; overflow-x: hidden; opacity: 0; + visibility: hidden; transform: translateY(10px); pointer-events: none; bottom: var(--art-control-height); max-height: var(--art-selector-max-height); background-color: var(--art-widget-background); - transition: all var(--art-transition-duration) ease; + transition: opacity var(--art-transition-duration) ease, transform var(--art-transition-duration) ease; .art-selector-item { .art-center(); @@ -38,9 +39,11 @@ } } - &:hover { + &:hover:not(.art-selector-dismissed), + &.art-selector-open { .art-selector-list { opacity: 1; + visibility: visible; transform: translateY(0); pointer-events: auto; } diff --git a/packages/artplayer/src/style/volume.less b/packages/artplayer/src/style/volume.less index 50529124c..d2005564c 100644 --- a/packages/artplayer/src/style/volume.less +++ b/packages/artplayer/src/style/volume.less @@ -11,12 +11,13 @@ text-align: center; cursor: default; opacity: 0; + visibility: hidden; transform: translateY(10px); pointer-events: none; bottom: var(--art-control-height); width: var(--art-control-height); height: var(--art-volume-height); - transition: all var(--art-transition-duration) ease; + transition: opacity var(--art-transition-duration) ease, transform var(--art-transition-duration) ease; .art-volume-inner { display: flex; @@ -73,9 +74,11 @@ } } - &:hover { + &:hover, + &:focus-within { .art-volume-panel { opacity: 1; + visibility: visible; transform: translateY(0); pointer-events: auto; } diff --git a/packages/artplayer/src/utils/component.ts b/packages/artplayer/src/utils/component.ts index 596d2161c..6f7a77b45 100644 --- a/packages/artplayer/src/utils/component.ts +++ b/packages/artplayer/src/utils/component.ts @@ -1,6 +1,8 @@ import type { ComponentHost, Entry, EntryInput, EntryOption, EventCleanup } from '../component/types' import validator from 'option-validator' +import { keyboardButton } from '../accessibility/button' import { renderEntry } from '../component/dom' +import { captureComponentFocus } from '../component/focus' import { ownEntry, releaseEntry } from '../component/resources' import { isClosing } from '../lifecycle/instance' import { ComponentOption } from '../scheme' @@ -74,6 +76,9 @@ export default class Component { if (scope.closed) return if (option.click) { + const actionable = (this.name === 'control' && !option.selector) || (this.name === 'contextmenu' && !$ref.querySelector('[data-value]')) + if (actionable && !$ref.querySelector('button,input,select,textarea,a[href],[tabindex],[contenteditable]')) + keyboardButton(scope, $ref) const cleanup = this.art.events.proxy($ref, 'click', (event) => { if (scope.closed) return @@ -118,6 +123,7 @@ export default class Component { const item = this.cache.get(name)! if (removing.has(item)) return + const restoreFocus = captureComponentFocus(this, item.$ref) removing.add(item) try { if (item.option.beforeUnmount) @@ -135,17 +141,24 @@ export default class Component { } finally { removing.delete(item) + restoreFocus() } } update(option: EntryOption): ReturnType { - if (this.cache.has(option.name!)) { - const item = this.cache.get(option.name!)! - option = Object.assign(item.option, option) - this.remove(option.name!) + const restoreFocus = captureComponentFocus(this, this.cache.get(option.name!)?.$ref, option.name) + try { + if (this.cache.has(option.name!)) { + const item = this.cache.get(option.name!)! + option = Object.assign(item.option, option) + this.remove(option.name!) + } + // add is polymorphic: Control intentionally returns undefined. + return this.add(option) as ReturnType + } + finally { + restoreFocus() } - // add is polymorphic: Control intentionally returns undefined. - return this.add(option) as ReturnType } } diff --git a/packages/artplayer/types/i18n.d.ts b/packages/artplayer/types/i18n.d.ts index 9cf0cb51d..60faae115 100644 --- a/packages/artplayer/types/i18n.d.ts +++ b/packages/artplayer/types/i18n.d.ts @@ -1,10 +1,15 @@ // Generated from public/i18n.ts by yarn build:types. Do not edit. type I18nKeys = 'en' | 'zh-cn' | 'zh-tw' | 'pl' | 'cs' | 'es' | 'fa' | 'fr' | 'id' | 'ru' | 'tr' | 'ar' | 'vi' | (string & Record) interface I18nValue { + 'Context Menu'?: string + 'Lock'?: string 'Video Info': string 'Close': string 'Video Load Failed': string 'Volume': string + 'Progress'?: string + 'Back'?: string + 'Settings'?: string 'Play': string 'Pause': string 'Rate': string diff --git a/refactor/baselines/keyboard-buttons-partial.json b/refactor/baselines/keyboard-buttons-partial.json new file mode 100644 index 000000000..5aedcac5e --- /dev/null +++ b/refactor/baselines/keyboard-buttons-partial.json @@ -0,0 +1,812 @@ +{ + "task": "CORE-23", + "status": "partial-buttons-focus", + "capturedAt": "2026-09-11T10:18:33.135Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "source": { + "packages/artplayer/src/accessibility/button.ts": "f6f67e19bbee2f1fa6a82828c451bcb86b5b1062575de411a0e72313a38c1c06", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "a25464e14216b2be392fcb3fdda2439e6d6f98d1962f0acbba30e3bd53bcb2d4", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "42c192d23e347d74e0bb814697a4d59eac20afbec102a282d5aa15780cab5f72", + "packages/artplayer/src/contextmenu/index.ts": "4fd292a931b5bda9f16a1c2bedd50cd0d8c0b8fb6010ffc5faaad2c197d2d9e5", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/playbackRate.ts": "e177f4017ea9291794fb4023715c81bfc01f927324ab9bd0e32c741e4a3b0ca7", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "f0876ddbdc01f812a5a776bdeefdff8dc52e557aff684f99b5ea7f6bfc8c0fb3", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector.ts": "fb055097eb38ea7cc488556ea52f3d185f437eb3de4dec7e09b601b01585d7c7", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "87d8d4b5a7a9b91a9682880a5159f7e701204ec33b9e04ab9324f3453f16b9eb", + "packages/artplayer/src/control/volume.ts": "46c83cec399345b844da224aa38255f4e4d05e262e8fb33fbacbe52b0bd3c965", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "83a6e5c6d1923332973009b7ac1561f7a55fb72e5c60e5ebc88af1fa4b641d5e", + "packages/artplayer/src/display/mini.ts": "3ffae49b1407523da2dc5f2bc687018268f6c1d1d3c71911dd4aa96d1a66c1dc", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "6f78b34b903fb30653cc7169f43861f8be426d1f6e9669ef292e41a1606d685c", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "dd2c5cf65cfe35d6b5a87d01acb28f48119b27fe6e5f0c6a8b9bab3db1a1923f", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "c1e41787c700096ecbc91de6558353f43d8930929ee312b7aa2c7da14a07ec75", + "packages/artplayer/src/i18n/cs.ts": "62c5ffcf3ac24e0dc2d7222b7ebb2b4d3454e9c04b80930a50defb3867d645be", + "packages/artplayer/src/i18n/es.ts": "5d31184b41ef29c1544c91ff08e3bbf9fc5c5776f0af0aa0238f90a9d161b9b1", + "packages/artplayer/src/i18n/fa.ts": "1294b91178ebdc7bc26d14a6f407ba8598207ae0dc812f3b821b62b7bf0089e5", + "packages/artplayer/src/i18n/fr.ts": "7125c0011b90f507d5b5fe20afd875992b62af9cdd44f02bbabed051c4ebc107", + "packages/artplayer/src/i18n/id.ts": "0d2e79cc0118cff6be83786a3fc048461785a64bdffc6bc45ffb68cb595f6da4", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "f6fb58a0d3fa118e22cfa6df5edd74c7bf39dc9ff1d416fb2b01e1bb8708b06f", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "473c43197acec10991b0f67814f79421dfe9ec4f534fb15413a32cf2a4d8ad38", + "packages/artplayer/src/i18n/tr.ts": "7b6afbbe452c4907c8bef36663bd218fd140bd1a4b3c776f31c53415e78e8f16", + "packages/artplayer/src/i18n/vi.ts": "29ea7f23d7400c847596632c86a4ca10c39cbafe1e6d723ed099b819aca7e764", + "packages/artplayer/src/i18n/zh-cn.ts": "22584521b0aa92da5278b01581e6e8e5bb3a23a2c3029e9df8642b7f0bded392", + "packages/artplayer/src/i18n/zh-tw.ts": "8da94a4fd508176bbb6b7ce2f4ba6ef6a56e7b1229bc67cc42d1a7bde70a7e9d", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/poll.ts": "1d7a519dd1960c8cd5fb7a020d8d3dbcd2eb272b612d823f2167997751aaf663", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock.ts": "9a08cec3a92006be8a9d2dba8d850bc4f8f38d586a50de86d725d0d8929130fd", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f1e8a302077a8ccfa77c17ce344bdd6816943e77b5876c7f623314ff846742f7", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "853090bfffe579c5106124d64c8d2a646876448bcc7258740a96820d56508ad0", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a1bc04b99bda45cc1a2afcf2dd0925c88ccb55e169b971105277883ae2ccba0c", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "08298ce2c04b5c909b3cc9b1071d2e3e91a7096ba878165a55073e20c33321b0", + "packages/artplayer/src/setting/update.ts": "949c0001e9ae10c08ad9a9fce1c88603d98a9cb9b7ac5fa6620ee00a07933187", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "35d3fabf5415606a0bcf4c5f6c519d8b005a63ce1f1aeef67c75d0b37925266d", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "2da8fcde7d38ca29cd1e42cd57ab0b0d47fde2a2866bbd33223f5c8e459472b5", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "927fd6c6c5ab440a2b25ecc43211ab89106c739385385b62de3880ed45dd7601", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "589d05e12a62e04fe848b36ba748433d23f0b909a04e861b1d6737f2799be183", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "295012ba379a7e957a24476616a0c3623d6a06e82ebbdaa45b916dd6412d7f4f", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "a3954794a9478d3872202b90d349c873cbb51639dcd7d1e3d73a55ce635fcd99", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "c8ff22ef3774cf7d97713638cb562f1bfc11aa113df5c625a2c20527ffc450ad", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "tooling": { + "package.json": "e229f7d1d2a2ce739ff71e81f0731c8ca5e2cd5db1495c885748f13960a762b9", + "test/accessibility-button.test.js": "ef769c55fc0ec603dd966e44dba4cbf1a5208960213db7edb75065503655c735", + "test/accessibility-focus.test.js": "ab7718f6e2615e6cce5362043f6a68ee51f556df7e4a993def36194a4e7225a1", + "test/browser/accessibility.spec.js": "dbb5eb78f54e1fb34dd33a229531201218d0169b0e0443908ae04f7534f1adbc", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c" + }, + "ci": { + "passed": 456, + "productionTypeScript": 232, + "logSha256": "5490430473aa64d471ca910ecc25402fe6878ae34e865ae7640b45ac4297ecf8" + }, + "browser": { + "stats": { + "startTime": "2026-09-11T10:14:10.867Z", + "duration": 26968.483, + "expected": 69, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "4529077aeee0e14d113478684ecbf06970a52e30edf312b8841579494cfea6b6", + "cases": [ + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "passed": true + } + ], + "reportSha256": "ad537a08516746b05d646b64874f971243c0c049964f2f34a200e5fee09fb24e" + }, + "probes": [ + { + "name": "core23-tab-before", + "stats": { + "startTime": "2026-09-11T09:59:37.648Z", + "duration": 10403.492, + "expected": 1, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "780609ae9d3abcd573f4656555587ce2b1ad7f5fc2cf42ec9a7a6dca73dc6a99", + "failures": [ + { + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-playAndPause')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-control-playAndPause') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-playAndPause')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 27 | await page.keyboard.press('Tab')\n 28 | const play = page.locator('.art-control-playAndPause')\n> 29 | await expect(play).toBeFocused()\n | ^\n 30 | await expect(play).toHaveAttribute('role', 'button')\n 31 | await expect(play).toHaveAttribute('aria-label', 'Play')\n 32 | await page.keyboard.press('Enter')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility.spec.js:29:22" + ] + } + ] + }, + { + "name": "core23-firefox-tab-probe", + "stats": { + "startTime": "2026-09-11T10:07:29.727Z", + "duration": 11754.319000000001, + "expected": 0, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "30333ddddf2f1c999fe3e78167cd92c48f649f31f0bb8a0fc5dd51ba2ef8f47e", + "failures": [ + { + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('#play')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('#play') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('#play')\u001b[22m\n\u001b[2m 17 × locator resolved to \u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 20 | await page.keyboard.press('Tab')\n 21 | console.log('Tab focus probe', await page.evaluate(() => ({ tag: document.activeElement.tagName, className: document.activeElement.className, html: document.activeElement.outerHTML.slice(0, 300) })))\n> 22 | await expect(page.locator('#play')).toBeFocused()\n | ^\n 23 | expect(await page.locator('.art-controls [tabindex=\"0\"]').count()).toBe(0)\n 24 | })\n 25 |\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility.spec.js:22:39" + ] + } + ] + }, + { + "name": "core23-pointer-focus-before", + "stats": { + "startTime": "2026-09-11T10:12:12.449Z", + "duration": 10358.796, + "expected": 0, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "de4e873006d7284271f330bc95f33786d54009c1b7a1655361fec6324f28a368", + "failures": [ + { + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mfalse\u001b[39m\nReceived: \u001b[31mtrue\u001b[39m\n\nCall Log:\n- Timeout 7000ms exceeded while waiting on the predicate\n\n 151 | })\n 152 | await page.mouse.move(900, 650)\n> 153 | await expect.poll(() => page.evaluate(() => window.art.controls.show)).toBe(false)\n | ^\n 154 | await expect.poll(() => page.locator('.art-bottom').evaluate(element => getComputedStyle(element).opacity)).toBe('0')\n 155 | })\n 156 |\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility.spec.js:153:74" + ] + } + ] + } + ], + "remaining": [ + "CORE-23 remains doing, BASE-DOM-01 open, no completed-task commit.", + "Progress/volume sliders, control selectors, settings tree and focus restoration, mode exit, dynamic focus removal, multi-instance/SSR and subtitle accessibility still require implementation/audit.", + "These are source-build browser results, not validation of freshly packed modern/legacy artifacts or a full browser matrix.", + "Physical devices and screen-reader certification remain release gates; no npm publication, push, tag or merge." + ] +} diff --git a/refactor/baselines/keyboard-contextmenu-partial.json b/refactor/baselines/keyboard-contextmenu-partial.json new file mode 100644 index 000000000..6a6d9b1c6 --- /dev/null +++ b/refactor/baselines/keyboard-contextmenu-partial.json @@ -0,0 +1,2757 @@ +{ + "task": "CORE-23", + "status": "partial-contextmenu", + "capturedAt": "2026-09-11T12:38:34.178Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "source": { + "packages/artplayer/src/accessibility/button.ts": "e5afa7aade56116082f54678c44961157950fa550d66e21a4e1ff9bb5369a6f8", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/accessibility/moved-focus.ts": "c3d2a7d496381b2a86819b82fbd26cc940a1204fdf19408ccc8db267741d96c9", + "packages/artplayer/src/accessibility/overlay-focus.ts": "93fa088daaa3afed88f645507828a10cb63292937c49b16f6c2a0ea895897878", + "packages/artplayer/src/accessibility/player-focus.ts": "e8fd5222cbfc38cd4938324c83d9f5cef3d01a439464e1570d63a5131c84f20a", + "packages/artplayer/src/accessibility/slider.ts": "533d5e6d806c32a84a578b43ed50993d30b4a414b5a85a34bbc68c37c5673a44", + "packages/artplayer/src/accessibility/suspend-focus.ts": "d95c6097236be66e252165287435cca01b50553d64259add6b011721e4bbc644", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/focus.ts": "f4aff802711f6146c80e8c6bd90bc2cb406ccbdb581aef41f436ff5c03871ad3", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "18ab60c9acee1e0cecd76c0b6cf750763eed7cfbede4220328b5200154c5c478", + "packages/artplayer/src/contextmenu/choices.ts": "6bb880b27afc9457442c3973992da6dc8da48fc61d6b66b3b5a3bb4fc4651dc8", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "a7a4ac375da45dc7b6c996d4534098838646a078abfc4438f688e91e14ef0b38", + "packages/artplayer/src/contextmenu/index.ts": "7532165d162fa463f1fe3c538d6bda0f579b5907b05137382efeb0018719b011", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/keyboard.ts": "eaa1af6b1abf8947d957208a0535f1b34f6c88e95394efd56cae905ccdea564c", + "packages/artplayer/src/contextmenu/playbackRate.ts": "7e06bb6fab3acdd71fb3ed63f77083172af517b49c1ecaefa3ee6a9068bdfe54", + "packages/artplayer/src/contextmenu/position.ts": "851ed1a884a13fbe430be77e7f72ae46d8a719175647e058644834aabd27ac58", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "629c622864619e2515b2eacb1bdfcf523ccce7ce680c8fdf51812e8e50a0cc7e", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/keyboard.ts": "03d1d47e6641ea08f765d731f10a6aad35f7c3edc16aa97df822c5f9a7f75eb0", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector-keyboard.ts": "6a749f48b23cda62148298e648bb380a6067cc18c7be4258b9ec85c382a56165", + "packages/artplayer/src/control/selector.ts": "a6f0c564c674530da9a0e4ed8762c6dfb81fa89373d64313e1020550731441f6", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "454846310d4fc3a8576ba030c2e8428bb795cde7b89308d29943bb4d4bc2aaa4", + "packages/artplayer/src/control/volume.ts": "45474d8d7f43d59263aa42e774eaaafeb45530ec24b81a5f589f6c906954568b", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-focus.ts": "1f717619e183b1cfab668bd2e41c8e9ba02210c94cdb58034ec97aa41e71aa34", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "bbe69e4419ffc0f6c744cb730a51778f23c311a0fac157223bcf8d8bf0f3edc7", + "packages/artplayer/src/display/mini.ts": "a6fed598428bbf8d52931f21bb68b7560a3643d2576f7e7bfbae98b2f7cdd1e5", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "e88c868fd370fcc9dc612489992d446a8d0558bd87c26c5c05fdd73d8a3d1b02", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "bc091e6dcfb28784dd40ea619ce1fb9061b9e85dcc5bf2b6a303679eee5c727d", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "897d8935384da16c3c4e96480777fe7fc022f6e3c0d87f62f79ae5f3c98e228c", + "packages/artplayer/src/i18n/cs.ts": "cc154ee50d258495d04dd2d49e89e9c0166e8b368969c443ec80cb5e48cf357c", + "packages/artplayer/src/i18n/es.ts": "0ed0283cb78847d6d1674be8c8ffa45feab88beaa8dbd11954b793c7b1657c75", + "packages/artplayer/src/i18n/fa.ts": "a72e83717f2e3e8f19f1de82516aef4a54ea70563223637bcbb25d21e9eac084", + "packages/artplayer/src/i18n/fr.ts": "a7366c75530e87f069216e20a6f09da42f7e77fdce862c02b32acf311068124b", + "packages/artplayer/src/i18n/id.ts": "146bf4c4e5bb39d8e1eb1a6fe3c639eb3128c55789de20511201f8ec02c56c0e", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "420f3b620d5c7ccdeba7857872be6176239fdf5da30b9cc72341e85dc95c2c8d", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "9a9f61e6a66b3cd884c609250bf765dcdbc850dae3270d8a1600a5c2542436d3", + "packages/artplayer/src/i18n/tr.ts": "631c262a5e6cd00fada5bf2e146007d845816e47edb7643ec792250a403e4ec6", + "packages/artplayer/src/i18n/vi.ts": "e6f3f8e53599e27755e162c76c3b049457aae7089eca73ee531986e67f517f6f", + "packages/artplayer/src/i18n/zh-cn.ts": "51eb75562ae1ae4e248e1db85c90bcbc69b388a177ada6cbf8c3196a2c343ac6", + "packages/artplayer/src/i18n/zh-tw.ts": "6b098739e27ad531172d0f13e53849be30e9936365ce9613a7d938d9f01cce53", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/keyboard.ts": "13a6f617514388b4d14e0bf752780937f2baf545edb216b8259f56a198112c83", + "packages/artplayer/src/info/poll.ts": "d26ff67d9eadf1e032445371dde6f15293a7fc0b2ae6b87c3815e4b4e1ed5dda", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock-keyboard.ts": "d59ac2fc9d0daf48c7946e0b49698a74e01f5f55e903c1b090fbda5516cbd16f", + "packages/artplayer/src/plugins/lock.ts": "8f5fe4469787b7b2a0a302d0fbd925f8eb6d1b261cae6e17367e4d97666a096c", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f6319af15ebe3600a466123dd9d343b86a8d6ed201693ac7ac86dc1d674d477f", + "packages/artplayer/src/setting/keyboard-focus.ts": "2717ce081f9bace0af287759571aadaab7e95c4be3b109a3168311a439b7d158", + "packages/artplayer/src/setting/keyboard-item.ts": "d94bfc0266486615ddb79b9eee3886f48891ebb2e5f465652ef98f142ada89d2", + "packages/artplayer/src/setting/keyboard.ts": "14781e4308b2ea7043314e88fb40f379a3dcfb4c97f10508b96b3455a05c3286", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "ed73745f2c7e2d76bbe8ce7202336e5f4de217dc8f0806b769127cb25316faba", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a642e630924eaf4ad91705fad1fa6e6dc946b32970d809a23da274399fce20ef", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "21a07d75a28bbbe20b3e107b6f1a09cb6f8ef2773ea10a4bd7caa88956e9b99c", + "packages/artplayer/src/setting/update.ts": "79326cb55c52243a7aa8df347a3b081dcd84eb7932fc6162061cc0d9f7078add", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "da98a47e8419b33069191e51fc94cc9652302ee4f3eff8ccc7a6dbd4c4c0e2bc", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "eb9cfe282c64a059d2e102280750bcd33ac33726fa09042eb9875f534335efef", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "8be782a3054154ab908b1cce650b6131330cf0f0e936b749accb4b2dfe605a27", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "ea345094ea5708dd3a3c290f357dbb301b38af35464d213c47e3ec6c60eaadca", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "44585c6b0179e34d21eeefce6d3494faacc0e9d108079426876e8847fd441513", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "6e99bbe0dbcb40667ef99789b65812dc9c94ce8a1071c00d2edec5eba041c434", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "c3fa96467e8b315d974a42a19591aa4a4a7514853db796135b2acbcdcb160ea3", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "publicTypes": { + "docs/assets/ts/artplayer.d.ts": "652c0fdf605e87203526777a05851bd69c95c1660d5ff29eab19c00967c9a985", + "packages/artplayer/public/artplayer.cts": "0e91e907d021db02a68004603e6190505fdc0806d873ebb6af171aa089a81da7", + "packages/artplayer/public/artplayer.mts": "f6292596a9ccb1d43a6d6a12c35f859b1889ad15924c5ae0f9f280941aade313", + "packages/artplayer/public/artplayer.ts": "26a42ac66811e70f68a8ebe62cbf304eb1993451b3e658961be98e7106162527", + "packages/artplayer/public/component.ts": "aa1c43be67322781b4b355b143bc69d9f29d22e578e4974d6a13e957a7c0334f", + "packages/artplayer/public/config.ts": "c4fd8681bf32b10c743e3e561c532520c8f32e43fd765524850b15e55cb91c72", + "packages/artplayer/public/cssVar.ts": "e027d82fb4f01c9ce7559cf679b2d5ee1962d3f7e5b4dd64ca21f472b933efb6", + "packages/artplayer/public/emitter.ts": "9c62551cdcc6dd3966bed8a7a85dd477435db977c91a294d2ac8f162f9592537", + "packages/artplayer/public/events.ts": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "packages/artplayer/public/i18n.ts": "34b0c684668044f7600c80b9d3979f8fb730138007b7cb4e7034326b340156fb", + "packages/artplayer/public/icons.ts": "0d8e8e52e52130dd4a29bab551dd7a2a954797e42e92a6e068c85d583e23e6a4", + "packages/artplayer/public/language.cts": "2248040d86a8e34626755c4ecf53ea0174706c653073cf0e15884a030d173120", + "packages/artplayer/public/language.mts": "c391e863012c77769e661afbf8fa949e9373aa88d17f58cbba7f5696edb8077f", + "packages/artplayer/public/legacy/language.ts": "c452ffd764ff9b29b819b3475c42395d2ea7a33560d8c186ef5df3844b9524c3", + "packages/artplayer/public/option.ts": "850e5264219b8b438c80694402225b690b131786677a5da0d22739ec2352d263", + "packages/artplayer/public/playback.ts": "1ceaed3aa1cef511fe8b20f4874647f6065c723ad805b742a0a9247e16bb1bb5", + "packages/artplayer/public/player.ts": "f1e50257df2ea592d0a0e1f36078dda77eaf2cf3b3d795307501396562d99f28", + "packages/artplayer/public/plugin.ts": "2a57e148fda00ee687da5036b890b0f611cb94bb403a1ed52602179060259d35", + "packages/artplayer/public/quality.ts": "7ed6ed78cea52991b2f6ddd2bd3b7bd8c5146fdfff7486fe8b814c3e632f1567", + "packages/artplayer/public/runtime.cts": "52cfff1daeb6841a90212c8fa8d46ca46d6650bb7ed1b59b62115d854b8ad652", + "packages/artplayer/public/runtime.mts": "1b09bc0ee0f0ee2f788689eaff441bdeda1fab0ce783e71b61b9792d81072b03", + "packages/artplayer/public/runtime.ts": "ec4b1d56993eb482a77eb0f94b701047549d009e6ba6433f27e7d464fef30c2b", + "packages/artplayer/public/runtime/component.ts": "840213299c942fe058eb5436977ceec066b9dccda24c55ae9f464b399c979e39", + "packages/artplayer/public/runtime/construction.ts": "24cc5cda1f614314db382271a9b0d5583b781894cfdf6c548700b1b5270467ee", + "packages/artplayer/public/runtime/events.ts": "52848f57d35eb1037cf74c8877521edf99a015bcd77f30ef6bbcba1807a99bfe", + "packages/artplayer/public/runtime/media.ts": "8828f80953aec3e95328cefe691661e8897cb27cb309483cf806ec45a8549ae3", + "packages/artplayer/public/runtime/option.ts": "bb672e49ffe74a6fc78543217f6de80d7d738890146df0857c709d4dc283e4ce", + "packages/artplayer/public/runtime/player.ts": "a4a24794e26cfb9e4310bf0f459a7a407e85bf81b4f3a4feb6294331af8036fb", + "packages/artplayer/public/runtime/plugin.ts": "9ad482f2a77914a91450419680b8af6b314b926f0831c2f7f6d7c466690f95c9", + "packages/artplayer/public/runtime/services.ts": "8e4648d8c61bff47343f9e1c2b995af69fc00947264b826109ceadcbaf553254", + "packages/artplayer/public/runtime/setting.ts": "c48d20957b57f79f985ef76a2950cc8a5cfa25dafa8ec5939e562661778e6218", + "packages/artplayer/public/runtime/subtitle.ts": "13241c4f9a87517aa2cf7b3e0bb8cedaa12fa0b4d3f8934285797583b752557e", + "packages/artplayer/public/runtime/template.ts": "da9975513a1938e7f386f4f65f718f0fc595164bfeac8f0cd99a3e97a54919a1", + "packages/artplayer/public/runtime/utils.ts": "cab9916f5224a3b047812b9f759cc9cc62105662599744067a6955020ab36916", + "packages/artplayer/public/setting.ts": "d12a75b656fff70cbb30be4bffec46d9c4273636e8722bce971a4d2b188712a1", + "packages/artplayer/public/subtitle.ts": "d25b470e47d6a9bd696d9c1ad8adb58e56a208f05695186d513bc8c43c2e8acf", + "packages/artplayer/public/template.ts": "68aed9e97d006d6be4fabb8504ca84dafab770b0925f4d6e7319e67c82f21b0d", + "packages/artplayer/public/utils.ts": "494ec447ab467a07ddd7a2c2abf778b3fce69fd28a09aaa8ced9759f8de2e3f6", + "packages/artplayer/types/COMPATIBILITY.md": "a7da9e102a116104b513df4f7451247b7759bc502d3375f30bd5b14a541826e0", + "packages/artplayer/types/README.md": "1bd9868e773610e6312fd48a1c5aa20772d29df0af40c3db66e75b7ab4a1aee0", + "packages/artplayer/types/artplayer.d.cts": "3685065e4263abcfd9d953176e461d5b3eb990b0363b54689a7f55deba770fef", + "packages/artplayer/types/artplayer.d.mts": "b664fec51ee5c5381f2ceab25d99d52aee56feab04a2ee7b4ea5b2145ea5fa0e", + "packages/artplayer/types/artplayer.d.ts": "5d0162adf7ac6d0f2bb9b5cfe361f28657c4d9c540cadbf36eba3cc954ce50f8", + "packages/artplayer/types/component.d.ts": "ae5bc1ddeaa1ee1ebbc62573e32423993727079205c64751a5a314170e588a32", + "packages/artplayer/types/config.d.ts": "36f9a84cd436f17701a0d11d3417fc1fe0414e0c52c80083b94a85dfc329e37e", + "packages/artplayer/types/cssVar.d.ts": "93217860fff2ebf750f606d95ddd22220a58837119e63bdf2f5f78fd7488458b", + "packages/artplayer/types/emitter.d.ts": "7e1f9a2a8ce65feb95734f1ed52d1334e57aa388bbef2a43d8bc53a9b6f6623c", + "packages/artplayer/types/events.d.ts": "f83624c9268a284477e8bd793fe3562a2363b72f2a44d5c64fe8c6a6cede8830", + "packages/artplayer/types/i18n.d.ts": "f4f2f05bdfda73c74fef34767cb18ee8e11b743120b1c4598e9714d7846018e5", + "packages/artplayer/types/icons.d.ts": "326a67ba7bdcf52862c5b2a269e540140aff98d05c7b96196485a77f84fe5960", + "packages/artplayer/types/language.d.cts": "f7928e108cf7b7814c2d75cb0a525333e95873fca6cd6d89a740450656b9c1cd", + "packages/artplayer/types/language.d.mts": "6619a26d604b7cccbe2f596243d87ae37cfaae33b8b52874ec071d9787446f9e", + "packages/artplayer/types/legacy/language.d.ts": "c7abda4d506fd933c350e9030290bf9e64347a921d683a66115da1995ebe0a81", + "packages/artplayer/types/option.d.ts": "ccf2c8ddc537dc65c9682d39f044726e23bff18f476b622512d7e6a4b949b5f6", + "packages/artplayer/types/playback.d.ts": "58705c273df6e76a77a6575e769a9ec6c013785c25080f2551aa22415788d870", + "packages/artplayer/types/player.d.ts": "92b00211b70ac71336e495899df972a0519dd138111846044fe4e0f967966177", + "packages/artplayer/types/plugin.d.ts": "fc3594a41c51d8248713e33c486fb1f6a518ac5c7ce31be6988a6cd8d052c5f3", + "packages/artplayer/types/quality.d.ts": "1ac1a48b4f74ff9ba1ce60443e1463d50d1c6a2e5d87d63dc7d2a8eb7f4c2c34", + "packages/artplayer/types/runtime.d.cts": "7ee988dfea9a0ac71a34a656f96f7b74e78aa92547cfdfab7ff7e1139a77d4a3", + "packages/artplayer/types/runtime.d.mts": "dcb85f59a8b7714918ced0c1d18c2bb24e8b80b56d8c594e019dcbdb5ad88b08", + "packages/artplayer/types/runtime.d.ts": "9c6ccd39a1be293f17ae46dae8ea077053e12635ee79d73a5e3b3a559230fcff", + "packages/artplayer/types/runtime/component.d.ts": "1b4c0cee44568649e80140fe778febfcae88af0ac85515f1cbeff78ab0c6d14f", + "packages/artplayer/types/runtime/construction.d.ts": "7a87bedf6f7ffff0c46078aa5f1551e0077d35574e286516121f5f935e2d9ce4", + "packages/artplayer/types/runtime/events.d.ts": "a1e2f9d387475453eaf95c2a5ee79e228636c0bb859bda3fcc46da46574a0c31", + "packages/artplayer/types/runtime/media.d.ts": "8fc89401be7fe25542c169d07dd5675f10916ed20be8493e19695966cf3864a8", + "packages/artplayer/types/runtime/option.d.ts": "6e334e1a76fdcc40b4665c02523bd31c3994d96078fadeb40e23422aa54c1a1d", + "packages/artplayer/types/runtime/player.d.ts": "8ac6383502e4872e83659838844856903031a81a0adc8e8535feb78453aa042c", + "packages/artplayer/types/runtime/plugin.d.ts": "8528f2b17843149f42f9cc16d6fd70baa238c9dc2c329b67d2c38096799c69bd", + "packages/artplayer/types/runtime/services.d.ts": "604c9f8e4b6c0da818f96576bf9f4b0e96085a9003927b2f7ba30027b1ba237e", + "packages/artplayer/types/runtime/setting.d.ts": "349c1fcb205ad312916bd3ee55e6bf241ea8a569fb2ab6c80822e69fc518f7d7", + "packages/artplayer/types/runtime/subtitle.d.ts": "269ff84678d327b3a9dc2f5bc6cc0d731d1e081b85422e474621d5d792efb153", + "packages/artplayer/types/runtime/template.d.ts": "7a62f968a38b4bf9109a4439557c02074eb1d62ba1f6e21a8eb194e91f0badfe", + "packages/artplayer/types/runtime/utils.d.ts": "6bf731705d86853e066dbaf3b8d4003b6548423fe615b7412b722bd0d3a6e48b", + "packages/artplayer/types/setting.d.ts": "08305a75dff96f06490430e099338b463df471b550c1d0dac3abc8995b39eb09", + "packages/artplayer/types/subtitle.d.ts": "b18314e2d64efdb6045830b6e12f615ae2ed585416130e562329ad3ea337f6ce", + "packages/artplayer/types/template.d.ts": "4792bc0c2cbcb7966e4375118bd34b326166e0831862e94ace4cf6b1bbe6a8c8", + "packages/artplayer/types/utils.d.ts": "fca0d3d814df94a25f9eb067c86fa0cf272e2791bac793b91229d57680797712" + }, + "tooling": { + "package.json": "315746ada69ccb62b8b8c10016b3e467667db9e39518b32dc8036cbade662ea4", + "test/browser/accessibility-contextmenu.spec.js": "f7d4be7e317abe7790bf7134479838b0d775974d33bd5bda97319708a6876b27", + "test/browser/accessibility-controls.spec.js": "d07d9919b9e9d960116770f82ebb61d165bd4b9fbc343a4e821d9cf9313dccef", + "test/browser/accessibility-info.spec.js": "348268395523d4fb5c2d9b6a2486cfb0d1e1b8ef84d13e97ad9db22f5e3ed173", + "test/browser/accessibility-lock.spec.js": "2c208fa3deda0f10769a95c697cb7618225897ede408d857d107706acae5e7f4", + "test/browser/accessibility-mini.spec.js": "a0d667265145ff24e37624775ae388f184ad425c4844c47ce8c692de31123a32", + "test/browser/accessibility-selector.spec.js": "aae91d2449e2257bfd19999505cf0bb5c631bd49b0dbf597ea1ac48e2f2a25d1", + "test/browser/accessibility-setting.spec.js": "067ace54bf2f73daed4d26c005daaaba09f292f7474825070f2dfbc0c50b544b", + "test/browser/accessibility-slider.spec.js": "b88aa23fc1b76e3a902150a8a9d4a801531f397b0a27120b4741baf67f82bc47", + "test/browser/accessibility.spec.js": "f10bdefdaac2359d1af5d2099cb8e1770bd7ca486362143f663b5c54459d6cab", + "test/browser/components.spec.js": "2be381b052b69baa3b4ae9cf2582593b9d611158e709e056aaa5df3cf969bef4", + "test/browser/display-mini.spec.js": "eecb351ef6c1b4d5a96c682e9d9b4507260473b10159bad0b918af277c2c58f3", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c", + "test/browser/prompt-components.spec.js": "2513a31306bb17b713aca2f9bc44f045ce34ac547482b4507955b0f1f14484ed" + }, + "ci": { + "passed": 468, + "productionTypeScript": 249, + "logSha256": "343a1580f31ae187b7898028293a7e79c157608fffa959715e6a330e6fd4ce3b" + }, + "browser": { + "stats": { + "startTime": "2026-09-11T12:35:20.129Z", + "duration": 118455.22, + "expected": 444, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "86035d7894aa83868c31d471c85c83716ea4382e3d6af862a04f0a6fd1839fcf", + "cases": [ + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "chromium" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "firefox" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "webkit" + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "webkit" + } + ], + "reportSha256": "ca6c1df45268b2a94256f729fd79148d01f9e358d8078419c48c2143dee83566" + }, + "screenshots": { + "refactor/.cache/core23-contextmenu-keyboard-chromium.png": "d807e470ab898c6c6a91064447e1a6b999bfc4daad16be7a97178f8c266e04be", + "refactor/.cache/core23-contextmenu-keyboard-firefox.png": "fe5e6db88f27fe43473c2ea38cc62cfc2d11d892ae90d81c2196731496fc3ed6", + "refactor/.cache/core23-contextmenu-keyboard-webkit.png": "e2ca9b030294d613bb51041fd1f15ee231e4f0b13322dfeeb2256de3ea344a71" + }, + "probes": [ + { + "name": "core23-contextmenu-before", + "stats": { + "startTime": "2026-09-11T12:22:14.311Z", + "duration": 18378.817, + "expected": 2, + "skipped": 0, + "unexpected": 4, + "flaky": 0 + }, + "reportSha256": "1636176572e7756e40b1f5254dfec6411ce39108e59eca18c523840a535836d5", + "failures": [ + { + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-contextmenu-info')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-contextmenu-info') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-contextmenu-info')\u001b[22m\n\u001b[2m 18 × locator resolved to
Video Info
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 16 | await setup(page)\n 17 | await page.keyboard.press('Shift+F10')\n> 18 | await expect(page.locator('.art-contextmenu-info')).toBeFocused()\n | ^\n 19 | expect(await page.evaluate(() => window.menuEvents)).toEqual([true])\n 20 | await page.keyboard.press('Enter')\n 21 | await expect(page.locator('.art-info-close')).toBeFocused()\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-contextmenu.spec.js:18:55" + ] + }, + { + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-contextmenu-info')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-contextmenu-info') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-contextmenu-info')\u001b[22m\n\u001b[2m 18 × locator resolved to
Video Info
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 32 | })\n 33 | await page.keyboard.press('ContextMenu')\n> 34 | await expect(page.locator('.art-contextmenu-info')).toBeFocused()\n | ^\n 35 | await page.keyboard.press('Escape')\n 36 | await expect(page.locator('.art-control-playAndPause')).toBeFocused()\n 37 | expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(true)\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-contextmenu.spec.js:34:55" + ] + }, + { + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-contextmenu-playbackRate [data-value]').first()\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-contextmenu-playbackRate [data-value]').first() with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-contextmenu-playbackRate [data-value]').first()\u001b[22m\n\u001b[2m 18 × locator resolved to 0.5\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 46 | await page.keyboard.press('Shift+F10')\n 47 | const choices = page.locator('.art-contextmenu-playbackRate [data-value]')\n> 48 | await expect(choices.first()).toBeFocused()\n | ^\n 49 | await page.keyboard.press('ArrowRight')\n 50 | await expect(choices.nth(1)).toBeFocused()\n 51 | expect(await page.evaluate(() => window.art.playbackRate)).toBe(1)\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-contextmenu.spec.js:48:33" + ] + }, + { + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-contextmenu-Beta')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-contextmenu-Beta') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-contextmenu-Beta')\u001b[22m\n\u001b[2m 18 × locator resolved to
Beta
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 69 | await page.keyboard.press('Shift+F10')\n 70 | await page.keyboard.press('b')\n> 71 | await expect(page.locator('.art-contextmenu-Beta')).toBeFocused()\n | ^\n 72 | await page.keyboard.press('Enter')\n 73 | expect(await page.evaluate(() => window.menuCalls)).toEqual([['Beta', true, true, 'click', true]])\n 74 | await expect(page.locator('.art-contextmenus')).toBeVisible()\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-contextmenu.spec.js:71:55" + ] + } + ] + }, + { + "name": "core23-contextmenu-first", + "stats": { + "startTime": "2026-09-11T12:26:14.487Z", + "duration": 10533.312999999998, + "expected": 5, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "a9bf8c66e6e2723a852aae6bddedeecda2e4db55eede5d685d696ce6d1b21c07", + "failures": [ + { + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-contextmenu-Alpha')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-contextmenu-Alpha') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-contextmenu-Alpha')\u001b[22m\n\u001b[2m 18 × locator resolved to
Alpha
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 76 | await expect(page.locator('.art-contextmenu-Beta')).toBeFocused()\n 77 | await page.evaluate(() => window.art.contextmenu.remove('Beta'))\n> 78 | await expect(page.locator('.art-contextmenu-Alpha')).toBeFocused()\n | ^\n 79 | })\n 80 |\n 81 | test('candidate: native context content retains input editing and button activation without nested roles', async ({ page }) => {\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-contextmenu.spec.js:78:56" + ] + } + ] + }, + { + "name": "core23-contextmenu-second", + "stats": { + "startTime": "2026-09-11T12:33:08.121Z", + "duration": 11470.374, + "expected": 10, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "fc05499df731d8fa8a817796072dcada9e36ed883944a85c03a4d81fdb681d56", + "failures": [ + { + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeHidden\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-contextmenus')\nExpected: hidden\nReceived: visible\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeHidden\" locator('.art-contextmenus') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-contextmenus')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"visible\"\u001b[22m\n\n\n 228 | })\n 229 | await page.keyboard.press('Shift+F10')\n> 230 | await expect(page.locator('.art-contextmenus')).toBeHidden()\n | ^\n 231 | await expect(page.locator('.art-control-playAndPause')).toBeFocused()\n 232 | await page.keyboard.press('Shift+F10')\n 233 | await expect(page.locator('.art-contextmenus')).toHaveAttribute('aria-label', '快捷菜单')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-contextmenu.spec.js:230:51", + "Error: Unhandled browser errors\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoEqual\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // deep equality\u001b[22m\n\n\u001b[32m- Expected - 1\u001b[39m\n\u001b[31m+ Received + 3\u001b[39m\n\n\u001b[32m- Array []\u001b[39m\n\u001b[31m+ Array [\u001b[39m\n\u001b[31m+ \"this.off is not a function\",\u001b[39m\n\u001b[31m+ ]\u001b[39m\n\n at fixtures.js:29\n\n 27 | }).catch(() => null)\n 28 | await testInfo.attach('browser-evidence', { contentType: 'application/json', body: JSON.stringify({ browser: browser.version(), platform: process.platform, manifest, state, errors, consoleErrors, failedRequests }, null, 2) })\n> 29 | expect(errors, 'Unhandled browser errors').toEqual([])\n | ^\n 30 | }, { auto: true }],\n 31 | })\n 32 |\n at Object.base.extend.diagnostics.auto (D:\\github\\ArtPlayer\\test\\browser\\fixtures.js:29:48)" + ] + } + ] + } + ], + "validationNotes": [ + "The first test incorrectly expected Alpha after removing Beta; actual DOM order and screenshot show the next action is Info. The test now verifies the next sibling and its focus.", + "The second probe incorrectly assumed an implicit art this for emitter listeners. The cancellation fixture now closes over window.art, preserving the historical emitter context contract.", + "After CI, only browser tests changed; the final browser file passed focused ESLint before the 444-case run. Runtime and declaration sources match the CI run.", + "Native editable context gesture checks assert unprevented events, not the appearance or operation of an OS context menu. Pointer position computation retains existing behavior.", + "Menu action callbacks and info/mini event sequence remain intact; overlay origin resolution only changes the destination of owned focus restoration." + ], + "remaining": [ + "CORE-23 remains doing and BASE-DOM-01 open. No completed-task commit.", + "Native mode exit focus, whole-player SSR/subtitle accessibility and final core acceptance still need work.", + "This is a Vite source build. Fresh installed modern/legacy artifacts and the full current browser matrix remain task-final gates.", + "Physical devices, screen readers and release reviews remain gates. No push, tag, merge or npm publication." + ] +} diff --git a/refactor/baselines/keyboard-control-focus-partial.json b/refactor/baselines/keyboard-control-focus-partial.json new file mode 100644 index 000000000..558b3338a --- /dev/null +++ b/refactor/baselines/keyboard-control-focus-partial.json @@ -0,0 +1,2959 @@ +{ + "task": "CORE-23", + "status": "partial-control-focus", + "capturedAt": "2026-09-11T11:43:44.165Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "source": { + "packages/artplayer/src/accessibility/button.ts": "e5afa7aade56116082f54678c44961157950fa550d66e21a4e1ff9bb5369a6f8", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/accessibility/moved-focus.ts": "c3d2a7d496381b2a86819b82fbd26cc940a1204fdf19408ccc8db267741d96c9", + "packages/artplayer/src/accessibility/player-focus.ts": "e8fd5222cbfc38cd4938324c83d9f5cef3d01a439464e1570d63a5131c84f20a", + "packages/artplayer/src/accessibility/slider.ts": "533d5e6d806c32a84a578b43ed50993d30b4a414b5a85a34bbc68c37c5673a44", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/focus.ts": "91b085394e8a70164cee4de9fd454b081d309e21528d9c2cb065a09a2e4f911c", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "a25464e14216b2be392fcb3fdda2439e6d6f98d1962f0acbba30e3bd53bcb2d4", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "42c192d23e347d74e0bb814697a4d59eac20afbec102a282d5aa15780cab5f72", + "packages/artplayer/src/contextmenu/index.ts": "4fd292a931b5bda9f16a1c2bedd50cd0d8c0b8fb6010ffc5faaad2c197d2d9e5", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/playbackRate.ts": "e177f4017ea9291794fb4023715c81bfc01f927324ab9bd0e32c741e4a3b0ca7", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "629c622864619e2515b2eacb1bdfcf523ccce7ce680c8fdf51812e8e50a0cc7e", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/keyboard.ts": "03d1d47e6641ea08f765d731f10a6aad35f7c3edc16aa97df822c5f9a7f75eb0", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector-keyboard.ts": "6a749f48b23cda62148298e648bb380a6067cc18c7be4258b9ec85c382a56165", + "packages/artplayer/src/control/selector.ts": "a6f0c564c674530da9a0e4ed8762c6dfb81fa89373d64313e1020550731441f6", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "a03d6810ce078d358d4a8d1db8ce1246bc59c8429dcdeb0640766a29719df08f", + "packages/artplayer/src/control/volume.ts": "45474d8d7f43d59263aa42e774eaaafeb45530ec24b81a5f589f6c906954568b", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "83a6e5c6d1923332973009b7ac1561f7a55fb72e5c60e5ebc88af1fa4b641d5e", + "packages/artplayer/src/display/mini.ts": "3ffae49b1407523da2dc5f2bc687018268f6c1d1d3c71911dd4aa96d1a66c1dc", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "6f78b34b903fb30653cc7169f43861f8be426d1f6e9669ef292e41a1606d685c", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "bc091e6dcfb28784dd40ea619ce1fb9061b9e85dcc5bf2b6a303679eee5c727d", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "1619066eace6d660be3266bc32f650b75bb09ab880269fd44f4037527583a834", + "packages/artplayer/src/i18n/cs.ts": "472403884eaf0fc10680c66f85e051d51c0efb34afe5e4876b157b5ca7594534", + "packages/artplayer/src/i18n/es.ts": "23a1b5647f031de45cf1c36243327cc64a740856101c2d45324c25e53698b207", + "packages/artplayer/src/i18n/fa.ts": "9d15b2217a49d8ccb9abfbb469d136cd7db9130eccad18ae3f2004e53c72541b", + "packages/artplayer/src/i18n/fr.ts": "a43e3d24ad4a5dca54d427c0db0c3c5278ed1798774546e1ce229a7e5cdcc713", + "packages/artplayer/src/i18n/id.ts": "c80af1d4d5e7b84e96634b3833949325dde7f136853ae3a57e112adec6187d58", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "c0ad26fdf7d94f10f032e22c7179303b1f229da9207cb4158838b6260bc38363", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "93b91342ba9a1f6aaa75fa991836dd8afc80616f0b2a4ab9c6e573b96645944b", + "packages/artplayer/src/i18n/tr.ts": "aeff1411c07be47a6dcd54716919cc06816538f31b809c912f95592132d91ec7", + "packages/artplayer/src/i18n/vi.ts": "1fd82ae49adea148885a8049fb9c2a05574da6778e8d83ae669b6667bde913f1", + "packages/artplayer/src/i18n/zh-cn.ts": "2dc774985b8d06091fdb2a21704ff400a36a1be80d6c3e1c41d1cdd173bd21c4", + "packages/artplayer/src/i18n/zh-tw.ts": "2e68092b3bc587a7b4e7a5a7597e46798af07e56dcc4eb69c5cb6ae9f6c1830c", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/poll.ts": "1d7a519dd1960c8cd5fb7a020d8d3dbcd2eb272b612d823f2167997751aaf663", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock.ts": "9a08cec3a92006be8a9d2dba8d850bc4f8f38d586a50de86d725d0d8929130fd", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f6319af15ebe3600a466123dd9d343b86a8d6ed201693ac7ac86dc1d674d477f", + "packages/artplayer/src/setting/keyboard-focus.ts": "2717ce081f9bace0af287759571aadaab7e95c4be3b109a3168311a439b7d158", + "packages/artplayer/src/setting/keyboard-item.ts": "d94bfc0266486615ddb79b9eee3886f48891ebb2e5f465652ef98f142ada89d2", + "packages/artplayer/src/setting/keyboard.ts": "14781e4308b2ea7043314e88fb40f379a3dcfb4c97f10508b96b3455a05c3286", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "ed73745f2c7e2d76bbe8ce7202336e5f4de217dc8f0806b769127cb25316faba", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a642e630924eaf4ad91705fad1fa6e6dc946b32970d809a23da274399fce20ef", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "21a07d75a28bbbe20b3e107b6f1a09cb6f8ef2773ea10a4bd7caa88956e9b99c", + "packages/artplayer/src/setting/update.ts": "79326cb55c52243a7aa8df347a3b081dcd84eb7932fc6162061cc0d9f7078add", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "da98a47e8419b33069191e51fc94cc9652302ee4f3eff8ccc7a6dbd4c4c0e2bc", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "2da8fcde7d38ca29cd1e42cd57ab0b0d47fde2a2866bbd33223f5c8e459472b5", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "927fd6c6c5ab440a2b25ecc43211ab89106c739385385b62de3880ed45dd7601", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "589d05e12a62e04fe848b36ba748433d23f0b909a04e861b1d6737f2799be183", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "44585c6b0179e34d21eeefce6d3494faacc0e9d108079426876e8847fd441513", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "6e99bbe0dbcb40667ef99789b65812dc9c94ce8a1071c00d2edec5eba041c434", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "8f82a43a5871a1b595d145831f1993755f114a74865faf2f2761b41bb4164c4a", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "tooling": { + "package.json": "315746ada69ccb62b8b8c10016b3e467667db9e39518b32dc8036cbade662ea4", + "test/browser/accessibility-controls.spec.js": "d07d9919b9e9d960116770f82ebb61d165bd4b9fbc343a4e821d9cf9313dccef", + "test/browser/accessibility-selector.spec.js": "aae91d2449e2257bfd19999505cf0bb5c631bd49b0dbf597ea1ac48e2f2a25d1", + "test/browser/accessibility-setting.spec.js": "067ace54bf2f73daed4d26c005daaaba09f292f7474825070f2dfbc0c50b544b", + "test/browser/accessibility-slider.spec.js": "b88aa23fc1b76e3a902150a8a9d4a801531f397b0a27120b4741baf67f82bc47", + "test/browser/accessibility.spec.js": "f10bdefdaac2359d1af5d2099cb8e1770bd7ca486362143f663b5c54459d6cab", + "test/browser/components.spec.js": "2be381b052b69baa3b4ae9cf2582593b9d611158e709e056aaa5df3cf969bef4", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c", + "test/browser/progress-quality.spec.js": "824596e3f0f1a7d8304ca7fed38de4f00b2f967eb87fd48346ad714fbb2e280f", + "test/browser/prompt-components.spec.js": "2513a31306bb17b713aca2f9bc44f045ce34ac547482b4507955b0f1f14484ed", + "test/browser/setting-interaction.spec.js": "030266515b16e1bf8677b30e7748f6a6451b10eba541c5ead9a54b5e57bb05b6", + "test/browser/setting-ownership.spec.js": "ef345200701ef826faa7c3aca564726bc9fad6587cc0af091c579d78ee7f3b4e", + "test/browser/setting-update.spec.js": "2f61a9790ebbdb0f3d86adfc2f9bce5e789806af2517403a47d5c02f1eddd1b1", + "test/browser/setting.spec.js": "19acfd07cb6316381e3bce61e0ae284303aeafc8fca14e1657d73568553c5bb6" + }, + "ci": { + "passed": 468, + "productionTypeScript": 241, + "logSha256": "d8cb80523e9f7180228e66e4085a5f8a0758cfa2fb54f99a59ea47179832d755" + }, + "browser": { + "stats": { + "startTime": "2026-09-11T11:40:29.902Z", + "duration": 145657.764, + "expected": 507, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "7d7e7f8833a596fc4ff6cd9eccf8c76cd369d158d1577f1485db6c75f6fd9076", + "cases": [ + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "webkit" + } + ], + "reportSha256": "9a889ee97e2572efc283f79d67bdb6c754d6dd0efb2c2dd91620131b6866985e" + }, + "probes": [ + { + "name": "core23-control-focus-before", + "stats": { + "startTime": "2026-09-11T11:35:32.389Z", + "duration": 18344.592, + "expected": 1, + "skipped": 0, + "unexpected": 5, + "flaky": 0 + }, + "reportSha256": "c5158b5bd678473d60983fc85b9e331a6ee68186fea560debe40134452c9c483", + "failures": [ + { + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-first')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-control-first') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-first')\u001b[22m\n\u001b[2m 18 × locator resolved to
Updated
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 34 | })\n 35 | expect(result).toBeUndefined()\n> 36 | await expect(control(page, 'first')).toBeFocused()\n | ^\n 37 | expect(await page.evaluate(() => window.focusOrder)).toEqual(['art-control art-control-first'])\n 38 | await page.keyboard.press('Space')\n 39 | expect(await page.evaluate(() => window.focusCalls)).toEqual([['first', true, true, 'click']])\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-controls.spec.js:36:40" + ] + }, + { + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-second')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-control-second') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-second')\u001b[22m\n\u001b[2m 18 × locator resolved to
second
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 44 | await control(page, 'first').focus()\n 45 | await page.evaluate(() => window.art.controls.remove('first'))\n> 46 | await expect(control(page, 'second')).toBeFocused()\n | ^\n 47 | await control(page, 'third').focus()\n 48 | await page.evaluate(() => window.art.controls.remove('third'))\n 49 | await expect(control(page, 'second')).toBeFocused()\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-controls.spec.js:46:41" + ] + }, + { + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-second')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-control-second') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-second')\u001b[22m\n\u001b[2m 18 × locator resolved to
second
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 62 | catch (error) { return error.message }\n 63 | })).toBe('mount failed')\n> 64 | await expect(control(page, 'second')).toBeFocused()\n | ^\n 65 | expect(await page.evaluate(() => {\n 66 | try {\n 67 | window.art.controls.update({ name: 'second', beforeUnmount() { throw new Error('veto') } })\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-controls.spec.js:64:41" + ] + }, + { + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-first')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-control-first') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-first')\u001b[22m\n\u001b[2m 18 × locator resolved to
Button
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 94 | await expect(control(page, 'first').locator('.art-selector-item').first()).toBeFocused()\n 95 | await page.evaluate(() => window.art.controls.update({ name: 'first', selector: undefined, html: 'Button', click() {} }))\n> 96 | await expect(control(page, 'first')).toBeFocused()\n | ^\n 97 | })\n 98 |\n 99 | test('candidate: removing the last focusable control leaves focus on the player without a permanent Tab stop', async ({ page }) => {\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-controls.spec.js:96:40" + ] + }, + { + "title": "candidate: removing the last focusable control leaves focus on the player without a permanent Tab stop", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-video-player')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-video-player') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-video-player')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 107 | await control(page, 'first').focus()\n 108 | await page.evaluate(() => window.art.controls.remove('first'))\n> 109 | await expect(page.locator('.art-video-player')).toBeFocused()\n | ^\n 110 | await expect(page.locator('.art-video-player')).not.toHaveAttribute('tabindex')\n 111 | })\n 112 |\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-controls.spec.js:109:51" + ] + } + ] + }, + { + "name": "core23-control-focus-first", + "stats": { + "startTime": "2026-09-11T11:36:51.076Z", + "duration": 10440.235, + "expected": 5, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "c2db49f391c3495807b13adeb055876c64b6ba9f3b63b1bd929dff075aae542a", + "failures": [ + { + "title": "candidate: removing the last focusable control leaves focus on the player without a permanent Tab stop", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-video-player')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-video-player') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-video-player')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 107 | await control(page, 'first').focus()\n 108 | await page.evaluate(() => window.art.controls.remove('first'))\n> 109 | await expect(page.locator('.art-video-player')).toBeFocused()\n | ^\n 110 | await expect(page.locator('.art-video-player')).not.toHaveAttribute('tabindex')\n 111 | })\n 112 |\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-controls.spec.js:109:51" + ] + } + ] + } + ], + "remaining": [ + "CORE-23 remains doing and BASE-DOM-01 open. No completed-task commit.", + "Remaining mode exit including mini/info/lock keyboard affordances, SSR/subtitle accessibility and whole-core acceptance still need work.", + "The dynamic-control suite now covers multi-instance focus isolation; this does not replace remaining whole-player cross-instance checks.", + "This is a Vite source build. Fresh installed modern/legacy artifacts and the full current browser matrix remain task-final gates.", + "Physical devices, screen readers and release reviews remain gates. No push, tag, merge or npm publication." + ] +} diff --git a/refactor/baselines/keyboard-info-lock-partial.json b/refactor/baselines/keyboard-info-lock-partial.json new file mode 100644 index 000000000..4506f2023 --- /dev/null +++ b/refactor/baselines/keyboard-info-lock-partial.json @@ -0,0 +1,2121 @@ +{ + "task": "CORE-23", + "status": "partial-info-lock", + "capturedAt": "2026-09-11T12:15:30.853Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "source": { + "packages/artplayer/src/accessibility/button.ts": "e5afa7aade56116082f54678c44961157950fa550d66e21a4e1ff9bb5369a6f8", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/accessibility/moved-focus.ts": "c3d2a7d496381b2a86819b82fbd26cc940a1204fdf19408ccc8db267741d96c9", + "packages/artplayer/src/accessibility/player-focus.ts": "e8fd5222cbfc38cd4938324c83d9f5cef3d01a439464e1570d63a5131c84f20a", + "packages/artplayer/src/accessibility/slider.ts": "533d5e6d806c32a84a578b43ed50993d30b4a414b5a85a34bbc68c37c5673a44", + "packages/artplayer/src/accessibility/suspend-focus.ts": "d95c6097236be66e252165287435cca01b50553d64259add6b011721e4bbc644", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/focus.ts": "91b085394e8a70164cee4de9fd454b081d309e21528d9c2cb065a09a2e4f911c", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "a25464e14216b2be392fcb3fdda2439e6d6f98d1962f0acbba30e3bd53bcb2d4", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "42c192d23e347d74e0bb814697a4d59eac20afbec102a282d5aa15780cab5f72", + "packages/artplayer/src/contextmenu/index.ts": "4fd292a931b5bda9f16a1c2bedd50cd0d8c0b8fb6010ffc5faaad2c197d2d9e5", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/playbackRate.ts": "e177f4017ea9291794fb4023715c81bfc01f927324ab9bd0e32c741e4a3b0ca7", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "629c622864619e2515b2eacb1bdfcf523ccce7ce680c8fdf51812e8e50a0cc7e", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/keyboard.ts": "03d1d47e6641ea08f765d731f10a6aad35f7c3edc16aa97df822c5f9a7f75eb0", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector-keyboard.ts": "6a749f48b23cda62148298e648bb380a6067cc18c7be4258b9ec85c382a56165", + "packages/artplayer/src/control/selector.ts": "a6f0c564c674530da9a0e4ed8762c6dfb81fa89373d64313e1020550731441f6", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "a03d6810ce078d358d4a8d1db8ce1246bc59c8429dcdeb0640766a29719df08f", + "packages/artplayer/src/control/volume.ts": "45474d8d7f43d59263aa42e774eaaafeb45530ec24b81a5f589f6c906954568b", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-focus.ts": "9a6b8280e8a443c87479a5806d1c85c2794038c38abc6f7ac8b85b63dc11086a", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "bbe69e4419ffc0f6c744cb730a51778f23c311a0fac157223bcf8d8bf0f3edc7", + "packages/artplayer/src/display/mini.ts": "a6fed598428bbf8d52931f21bb68b7560a3643d2576f7e7bfbae98b2f7cdd1e5", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "e88c868fd370fcc9dc612489992d446a8d0558bd87c26c5c05fdd73d8a3d1b02", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "bc091e6dcfb28784dd40ea619ce1fb9061b9e85dcc5bf2b6a303679eee5c727d", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "dc65797d0ab631709132a88a95b0864d5bc1f63c043339d29439b2cc991a07b5", + "packages/artplayer/src/i18n/cs.ts": "130973860e3623945cb45a54c9f380bd6252e37385e93af80979bc0a19cad878", + "packages/artplayer/src/i18n/es.ts": "7d8ae63e38efc6321b6496d1a9a478f19ed7ad2ad81ef6c32f38fe1d61f4e7cb", + "packages/artplayer/src/i18n/fa.ts": "34f85eea6750047ca8b26f738f6a7032fee6b9d381c5323c7fe522ec4a1608d5", + "packages/artplayer/src/i18n/fr.ts": "edf5b311da32025a17de99b54504289ccf8064924776258118b693cd0dc94c1c", + "packages/artplayer/src/i18n/id.ts": "8a30918a66804961345455a4da2d778dab189c88106eb4dcf6a9a273410a7392", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "d165a2047bf8211ea6e61c6a987d8e7338c1a7989fe184ec2bf19c7dc37d8ad7", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "0bd814ce1f63ab7532c9347aff8e44b11c9699324e9fba2a8667db6b7cc26589", + "packages/artplayer/src/i18n/tr.ts": "acc7367f7c9b2b7a1bdbeaf33d7d41396b31fbe4506a9d5d3bd3fe356908924f", + "packages/artplayer/src/i18n/vi.ts": "c7874d6b6e5e1121f15db96ce73926a772b02b0bb594d5e517de59ed2e23ace1", + "packages/artplayer/src/i18n/zh-cn.ts": "0b1ce684db923c6df1ff0349924c0aae659c31fca7e84d15e960ce972e7a0b0b", + "packages/artplayer/src/i18n/zh-tw.ts": "0c89f997ca07b170c76e4753b4f061faad4afa34c242300dd8ee737502a5aad3", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/keyboard.ts": "d49cb5e438461f30e2cb256d2e4eeee90854e50c275076748d32160f01a3afbf", + "packages/artplayer/src/info/poll.ts": "d26ff67d9eadf1e032445371dde6f15293a7fc0b2ae6b87c3815e4b4e1ed5dda", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock-keyboard.ts": "d59ac2fc9d0daf48c7946e0b49698a74e01f5f55e903c1b090fbda5516cbd16f", + "packages/artplayer/src/plugins/lock.ts": "8f5fe4469787b7b2a0a302d0fbd925f8eb6d1b261cae6e17367e4d97666a096c", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f6319af15ebe3600a466123dd9d343b86a8d6ed201693ac7ac86dc1d674d477f", + "packages/artplayer/src/setting/keyboard-focus.ts": "2717ce081f9bace0af287759571aadaab7e95c4be3b109a3168311a439b7d158", + "packages/artplayer/src/setting/keyboard-item.ts": "d94bfc0266486615ddb79b9eee3886f48891ebb2e5f465652ef98f142ada89d2", + "packages/artplayer/src/setting/keyboard.ts": "14781e4308b2ea7043314e88fb40f379a3dcfb4c97f10508b96b3455a05c3286", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "ed73745f2c7e2d76bbe8ce7202336e5f4de217dc8f0806b769127cb25316faba", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a642e630924eaf4ad91705fad1fa6e6dc946b32970d809a23da274399fce20ef", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "21a07d75a28bbbe20b3e107b6f1a09cb6f8ef2773ea10a4bd7caa88956e9b99c", + "packages/artplayer/src/setting/update.ts": "79326cb55c52243a7aa8df347a3b081dcd84eb7932fc6162061cc0d9f7078add", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "da98a47e8419b33069191e51fc94cc9652302ee4f3eff8ccc7a6dbd4c4c0e2bc", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "eb9cfe282c64a059d2e102280750bcd33ac33726fa09042eb9875f534335efef", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "8be782a3054154ab908b1cce650b6131330cf0f0e936b749accb4b2dfe605a27", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "ea345094ea5708dd3a3c290f357dbb301b38af35464d213c47e3ec6c60eaadca", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "44585c6b0179e34d21eeefce6d3494faacc0e9d108079426876e8847fd441513", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "6e99bbe0dbcb40667ef99789b65812dc9c94ce8a1071c00d2edec5eba041c434", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "8f82a43a5871a1b595d145831f1993755f114a74865faf2f2761b41bb4164c4a", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "publicTypes": { + "docs/assets/ts/artplayer.d.ts": "b78e811fbae9434e54598d00060e220b6f2fe0943de5328fc796183b96fc2aa6", + "packages/artplayer/public/artplayer.cts": "0e91e907d021db02a68004603e6190505fdc0806d873ebb6af171aa089a81da7", + "packages/artplayer/public/artplayer.mts": "f6292596a9ccb1d43a6d6a12c35f859b1889ad15924c5ae0f9f280941aade313", + "packages/artplayer/public/artplayer.ts": "26a42ac66811e70f68a8ebe62cbf304eb1993451b3e658961be98e7106162527", + "packages/artplayer/public/component.ts": "aa1c43be67322781b4b355b143bc69d9f29d22e578e4974d6a13e957a7c0334f", + "packages/artplayer/public/config.ts": "c4fd8681bf32b10c743e3e561c532520c8f32e43fd765524850b15e55cb91c72", + "packages/artplayer/public/cssVar.ts": "e027d82fb4f01c9ce7559cf679b2d5ee1962d3f7e5b4dd64ca21f472b933efb6", + "packages/artplayer/public/emitter.ts": "9c62551cdcc6dd3966bed8a7a85dd477435db977c91a294d2ac8f162f9592537", + "packages/artplayer/public/events.ts": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "packages/artplayer/public/i18n.ts": "864eff1a723b81990ad90eeabd3f5c1166f395ec6eaeb5f37299036ee6430417", + "packages/artplayer/public/icons.ts": "0d8e8e52e52130dd4a29bab551dd7a2a954797e42e92a6e068c85d583e23e6a4", + "packages/artplayer/public/language.cts": "2248040d86a8e34626755c4ecf53ea0174706c653073cf0e15884a030d173120", + "packages/artplayer/public/language.mts": "c391e863012c77769e661afbf8fa949e9373aa88d17f58cbba7f5696edb8077f", + "packages/artplayer/public/legacy/language.ts": "c452ffd764ff9b29b819b3475c42395d2ea7a33560d8c186ef5df3844b9524c3", + "packages/artplayer/public/option.ts": "850e5264219b8b438c80694402225b690b131786677a5da0d22739ec2352d263", + "packages/artplayer/public/playback.ts": "1ceaed3aa1cef511fe8b20f4874647f6065c723ad805b742a0a9247e16bb1bb5", + "packages/artplayer/public/player.ts": "f1e50257df2ea592d0a0e1f36078dda77eaf2cf3b3d795307501396562d99f28", + "packages/artplayer/public/plugin.ts": "2a57e148fda00ee687da5036b890b0f611cb94bb403a1ed52602179060259d35", + "packages/artplayer/public/quality.ts": "7ed6ed78cea52991b2f6ddd2bd3b7bd8c5146fdfff7486fe8b814c3e632f1567", + "packages/artplayer/public/runtime.cts": "52cfff1daeb6841a90212c8fa8d46ca46d6650bb7ed1b59b62115d854b8ad652", + "packages/artplayer/public/runtime.mts": "1b09bc0ee0f0ee2f788689eaff441bdeda1fab0ce783e71b61b9792d81072b03", + "packages/artplayer/public/runtime.ts": "ec4b1d56993eb482a77eb0f94b701047549d009e6ba6433f27e7d464fef30c2b", + "packages/artplayer/public/runtime/component.ts": "840213299c942fe058eb5436977ceec066b9dccda24c55ae9f464b399c979e39", + "packages/artplayer/public/runtime/construction.ts": "24cc5cda1f614314db382271a9b0d5583b781894cfdf6c548700b1b5270467ee", + "packages/artplayer/public/runtime/events.ts": "52848f57d35eb1037cf74c8877521edf99a015bcd77f30ef6bbcba1807a99bfe", + "packages/artplayer/public/runtime/media.ts": "8828f80953aec3e95328cefe691661e8897cb27cb309483cf806ec45a8549ae3", + "packages/artplayer/public/runtime/option.ts": "bb672e49ffe74a6fc78543217f6de80d7d738890146df0857c709d4dc283e4ce", + "packages/artplayer/public/runtime/player.ts": "a4a24794e26cfb9e4310bf0f459a7a407e85bf81b4f3a4feb6294331af8036fb", + "packages/artplayer/public/runtime/plugin.ts": "9ad482f2a77914a91450419680b8af6b314b926f0831c2f7f6d7c466690f95c9", + "packages/artplayer/public/runtime/services.ts": "8e4648d8c61bff47343f9e1c2b995af69fc00947264b826109ceadcbaf553254", + "packages/artplayer/public/runtime/setting.ts": "c48d20957b57f79f985ef76a2950cc8a5cfa25dafa8ec5939e562661778e6218", + "packages/artplayer/public/runtime/subtitle.ts": "13241c4f9a87517aa2cf7b3e0bb8cedaa12fa0b4d3f8934285797583b752557e", + "packages/artplayer/public/runtime/template.ts": "da9975513a1938e7f386f4f65f718f0fc595164bfeac8f0cd99a3e97a54919a1", + "packages/artplayer/public/runtime/utils.ts": "cab9916f5224a3b047812b9f759cc9cc62105662599744067a6955020ab36916", + "packages/artplayer/public/setting.ts": "d12a75b656fff70cbb30be4bffec46d9c4273636e8722bce971a4d2b188712a1", + "packages/artplayer/public/subtitle.ts": "d25b470e47d6a9bd696d9c1ad8adb58e56a208f05695186d513bc8c43c2e8acf", + "packages/artplayer/public/template.ts": "68aed9e97d006d6be4fabb8504ca84dafab770b0925f4d6e7319e67c82f21b0d", + "packages/artplayer/public/utils.ts": "494ec447ab467a07ddd7a2c2abf778b3fce69fd28a09aaa8ced9759f8de2e3f6", + "packages/artplayer/types/COMPATIBILITY.md": "a7da9e102a116104b513df4f7451247b7759bc502d3375f30bd5b14a541826e0", + "packages/artplayer/types/README.md": "1bd9868e773610e6312fd48a1c5aa20772d29df0af40c3db66e75b7ab4a1aee0", + "packages/artplayer/types/artplayer.d.cts": "3685065e4263abcfd9d953176e461d5b3eb990b0363b54689a7f55deba770fef", + "packages/artplayer/types/artplayer.d.mts": "b664fec51ee5c5381f2ceab25d99d52aee56feab04a2ee7b4ea5b2145ea5fa0e", + "packages/artplayer/types/artplayer.d.ts": "5d0162adf7ac6d0f2bb9b5cfe361f28657c4d9c540cadbf36eba3cc954ce50f8", + "packages/artplayer/types/component.d.ts": "ae5bc1ddeaa1ee1ebbc62573e32423993727079205c64751a5a314170e588a32", + "packages/artplayer/types/config.d.ts": "36f9a84cd436f17701a0d11d3417fc1fe0414e0c52c80083b94a85dfc329e37e", + "packages/artplayer/types/cssVar.d.ts": "93217860fff2ebf750f606d95ddd22220a58837119e63bdf2f5f78fd7488458b", + "packages/artplayer/types/emitter.d.ts": "7e1f9a2a8ce65feb95734f1ed52d1334e57aa388bbef2a43d8bc53a9b6f6623c", + "packages/artplayer/types/events.d.ts": "f83624c9268a284477e8bd793fe3562a2363b72f2a44d5c64fe8c6a6cede8830", + "packages/artplayer/types/i18n.d.ts": "31381ca70774b7cb50e32305b83adc7a554e4de7944fb2949e07b612c393f851", + "packages/artplayer/types/icons.d.ts": "326a67ba7bdcf52862c5b2a269e540140aff98d05c7b96196485a77f84fe5960", + "packages/artplayer/types/language.d.cts": "f7928e108cf7b7814c2d75cb0a525333e95873fca6cd6d89a740450656b9c1cd", + "packages/artplayer/types/language.d.mts": "6619a26d604b7cccbe2f596243d87ae37cfaae33b8b52874ec071d9787446f9e", + "packages/artplayer/types/legacy/language.d.ts": "c7abda4d506fd933c350e9030290bf9e64347a921d683a66115da1995ebe0a81", + "packages/artplayer/types/option.d.ts": "ccf2c8ddc537dc65c9682d39f044726e23bff18f476b622512d7e6a4b949b5f6", + "packages/artplayer/types/playback.d.ts": "58705c273df6e76a77a6575e769a9ec6c013785c25080f2551aa22415788d870", + "packages/artplayer/types/player.d.ts": "92b00211b70ac71336e495899df972a0519dd138111846044fe4e0f967966177", + "packages/artplayer/types/plugin.d.ts": "fc3594a41c51d8248713e33c486fb1f6a518ac5c7ce31be6988a6cd8d052c5f3", + "packages/artplayer/types/quality.d.ts": "1ac1a48b4f74ff9ba1ce60443e1463d50d1c6a2e5d87d63dc7d2a8eb7f4c2c34", + "packages/artplayer/types/runtime.d.cts": "7ee988dfea9a0ac71a34a656f96f7b74e78aa92547cfdfab7ff7e1139a77d4a3", + "packages/artplayer/types/runtime.d.mts": "dcb85f59a8b7714918ced0c1d18c2bb24e8b80b56d8c594e019dcbdb5ad88b08", + "packages/artplayer/types/runtime.d.ts": "9c6ccd39a1be293f17ae46dae8ea077053e12635ee79d73a5e3b3a559230fcff", + "packages/artplayer/types/runtime/component.d.ts": "1b4c0cee44568649e80140fe778febfcae88af0ac85515f1cbeff78ab0c6d14f", + "packages/artplayer/types/runtime/construction.d.ts": "7a87bedf6f7ffff0c46078aa5f1551e0077d35574e286516121f5f935e2d9ce4", + "packages/artplayer/types/runtime/events.d.ts": "a1e2f9d387475453eaf95c2a5ee79e228636c0bb859bda3fcc46da46574a0c31", + "packages/artplayer/types/runtime/media.d.ts": "8fc89401be7fe25542c169d07dd5675f10916ed20be8493e19695966cf3864a8", + "packages/artplayer/types/runtime/option.d.ts": "6e334e1a76fdcc40b4665c02523bd31c3994d96078fadeb40e23422aa54c1a1d", + "packages/artplayer/types/runtime/player.d.ts": "8ac6383502e4872e83659838844856903031a81a0adc8e8535feb78453aa042c", + "packages/artplayer/types/runtime/plugin.d.ts": "8528f2b17843149f42f9cc16d6fd70baa238c9dc2c329b67d2c38096799c69bd", + "packages/artplayer/types/runtime/services.d.ts": "604c9f8e4b6c0da818f96576bf9f4b0e96085a9003927b2f7ba30027b1ba237e", + "packages/artplayer/types/runtime/setting.d.ts": "349c1fcb205ad312916bd3ee55e6bf241ea8a569fb2ab6c80822e69fc518f7d7", + "packages/artplayer/types/runtime/subtitle.d.ts": "269ff84678d327b3a9dc2f5bc6cc0d731d1e081b85422e474621d5d792efb153", + "packages/artplayer/types/runtime/template.d.ts": "7a62f968a38b4bf9109a4439557c02074eb1d62ba1f6e21a8eb194e91f0badfe", + "packages/artplayer/types/runtime/utils.d.ts": "6bf731705d86853e066dbaf3b8d4003b6548423fe615b7412b722bd0d3a6e48b", + "packages/artplayer/types/setting.d.ts": "08305a75dff96f06490430e099338b463df471b550c1d0dac3abc8995b39eb09", + "packages/artplayer/types/subtitle.d.ts": "b18314e2d64efdb6045830b6e12f615ae2ed585416130e562329ad3ea337f6ce", + "packages/artplayer/types/template.d.ts": "4792bc0c2cbcb7966e4375118bd34b326166e0831862e94ace4cf6b1bbe6a8c8", + "packages/artplayer/types/utils.d.ts": "fca0d3d814df94a25f9eb067c86fa0cf272e2791bac793b91229d57680797712" + }, + "unitFixtures": { + "test/builtin-layers.test.js": "14af539fe85896a26fcc46891d56bb33adb0aac54dc273ad8061cb93ecdd0ebc", + "test/prompt-components.test.js": "c8328abace4cbb34d0f08780983cdf98406287018247a7ded5cc18d847b96c82" + }, + "tooling": { + "package.json": "315746ada69ccb62b8b8c10016b3e467667db9e39518b32dc8036cbade662ea4", + "test/browser/accessibility-controls.spec.js": "d07d9919b9e9d960116770f82ebb61d165bd4b9fbc343a4e821d9cf9313dccef", + "test/browser/accessibility-info.spec.js": "348268395523d4fb5c2d9b6a2486cfb0d1e1b8ef84d13e97ad9db22f5e3ed173", + "test/browser/accessibility-lock.spec.js": "2c208fa3deda0f10769a95c697cb7618225897ede408d857d107706acae5e7f4", + "test/browser/accessibility-mini.spec.js": "a0d667265145ff24e37624775ae388f184ad425c4844c47ce8c692de31123a32", + "test/browser/accessibility-selector.spec.js": "aae91d2449e2257bfd19999505cf0bb5c631bd49b0dbf597ea1ac48e2f2a25d1", + "test/browser/accessibility-setting.spec.js": "067ace54bf2f73daed4d26c005daaaba09f292f7474825070f2dfbc0c50b544b", + "test/browser/accessibility-slider.spec.js": "b88aa23fc1b76e3a902150a8a9d4a801531f397b0a27120b4741baf67f82bc47", + "test/browser/accessibility.spec.js": "f10bdefdaac2359d1af5d2099cb8e1770bd7ca486362143f663b5c54459d6cab", + "test/browser/builtin-layers.spec.js": "4efa0ebe413cbf0ca9b06074ce73ead337136bc477c4f8fda6665be0504a31eb", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c", + "test/browser/prompt-components.spec.js": "2513a31306bb17b713aca2f9bc44f045ce34ac547482b4507955b0f1f14484ed" + }, + "ci": { + "passed": 468, + "productionTypeScript": 245, + "logSha256": "9aa8933cd69a53de9e280533d4bf2be368ba024c11a0cbe52feb3426656de8df" + }, + "browser": { + "stats": { + "startTime": "2026-09-11T12:13:41.284Z", + "duration": 87030.972, + "expected": 306, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "3c7d961f40bbe894da833a075052962c897aab5ce72bfa8588c693fd3bcea372", + "cases": [ + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "chromium" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "firefox" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "webkit" + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "chromium" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "firefox" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "webkit" + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "chromium" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "firefox" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "webkit" + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "chromium" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "firefox" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "webkit" + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "webkit" + } + ], + "reportSha256": "311b6687aa10fc237f888df97c28f1e86bab00bd926ccec23fa5ff4ade84b6bd" + }, + "probes": [ + { + "name": "core23-info-keyboard-before", + "stats": { + "startTime": "2026-09-11T11:54:45.888Z", + "duration": 10639.716999999999, + "expected": 1, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "d39b379d786e2ecab2fa8f218578cf39158e4ac89623410d545b6165638b300f", + "failures": [ + { + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-info-close')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-info-close') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-info-close')\u001b[22m\n\u001b[2m 18 × locator resolved to
[x]
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 23 | await trigger.focus()\n 24 | await page.keyboard.press('Enter')\n> 25 | await expect(page.locator('.art-info-close')).toBeFocused()\n | ^\n 26 | await expect(page.locator('.art-info-close')).toHaveAttribute('aria-label', 'Close')\n 27 | await expect(page.locator('.art-info')).toHaveAttribute('aria-label', 'Video Info')\n 28 | await page.keyboard.press('Space')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-info.spec.js:25:49" + ] + }, + { + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeHidden\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-info')\nExpected: hidden\nReceived: visible\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeHidden\" locator('.art-info') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-info')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"visible\"\u001b[22m\n\n\n 66 | })\n 67 | await page.keyboard.press('Enter')\n> 68 | await expect(page.locator('.art-info')).toBeHidden()\n | ^\n 69 | await expect(page.locator('.art-control-info-trigger')).toBeFocused()\n 70 | expect(await page.evaluate(() => window.infoEvents)).toEqual([false])\n 71 | })\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-info.spec.js:68:43" + ] + }, + { + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-video-player')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-video-player') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-video-player')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 77 | await page.evaluate(() => window.art.controls.remove('info-trigger'))\n 78 | await page.keyboard.press('Escape')\n> 79 | await expect(page.locator('.art-video-player')).toBeFocused()\n | ^\n 80 | await page.evaluate(() => {\n 81 | window.retainedInfo = window.art.template.$infoClose\n 82 | window.art.destroy(false)\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-info.spec.js:79:51" + ] + } + ] + }, + { + "name": "core23-lock-keyboard-before", + "stats": { + "startTime": "2026-09-11T12:00:57.495Z", + "duration": 10261.756, + "expected": 0, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "84dde207a57451779afa59907d71e81109eaca2d145e8993e4c5da7235f5f34e", + "failures": [ + { + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-layer-lock')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-layer-lock') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-layer-lock')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 20 | const lock = page.locator('.art-layer-lock')\n 21 | await lock.focus()\n> 22 | await expect(lock).toBeFocused()\n | ^\n 23 | await expect(lock).toHaveAttribute('aria-label', 'Lock')\n 24 | await page.keyboard.press('Space')\n 25 | await expect(lock).toHaveAttribute('aria-pressed', 'true')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-lock.spec.js:22:22" + ] + }, + { + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-layer-lock')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-layer-lock') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-layer-lock')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 44 | window.art.plugins.lock.state = true\n 45 | })\n> 46 | await expect(page.locator('.art-layer-lock')).toBeFocused()\n | ^\n 47 | await expect(page.locator('.art-bottom')).toHaveAttribute('inert')\n 48 | await expect(page.locator('.art-control-custom button')).toHaveAttribute('tabindex', '-1')\n 49 | await page.keyboard.press('Enter')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-lock.spec.js:46:49" + ] + }, + { + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoHaveAttribute\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-late button')\nExpected: \u001b[32m\"-1\"\u001b[39m\nReceived: \u001b[31m\"\"\u001b[39m\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toHaveAttribute\" locator('.art-control-late button') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-late button')\u001b[22m\n\u001b[2m 17 × locator resolved to \u001b[22m\n\u001b[2m - unexpected value \"null\"\u001b[22m\n\n\n 58 | window.art.controls.add({ name: 'late', position: 'right', html: '' })\n 59 | })\n> 60 | await expect(page.locator('.art-control-late button')).toHaveAttribute('tabindex', '-1')\n | ^\n 61 | await page.evaluate(() => {\n 62 | window.retainedLock = window.art.layers.lock\n 63 | window.art.layers.remove('lock')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-lock.spec.js:60:58" + ] + } + ] + }, + { + "name": "core23-lock-keyboard-first", + "stats": { + "startTime": "2026-09-11T12:03:07.197Z", + "duration": 10293.706, + "expected": 17, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "847452a8c79ae05f16817b058a1b117dd06c35d9f96637533a008c4213e11784", + "failures": [ + { + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('#lock-outside')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('#lock-outside') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('#lock-outside')\u001b[22m\n\u001b[2m 18 × locator resolved to \u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 26 | await expect(lock).toBeFocused()\n 27 | await page.keyboard.press('Tab')\n> 28 | await expect(page.locator('#lock-outside')).toBeFocused()\n | ^\n 29 | await page.keyboard.press('Shift+Tab')\n 30 | await expect(lock).toBeFocused()\n 31 | await page.keyboard.press('Escape')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-lock.spec.js:28:47" + ] + } + ] + }, + { + "name": "core23-lock-remount-before", + "stats": { + "startTime": "2026-09-11T12:10:35.368Z", + "duration": 10190.961000000001, + "expected": 0, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "e6f95b5a4112bc044a87a98601556709c42d918cff1772c3f06f5a864dd46767", + "failures": [ + { + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoHaveCSS\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-layer-lock').locator('.art-icon-lock')\nExpected: \u001b[32m\"inline-flex\"\u001b[39m\nReceived: \u001b[31m\"none\"\u001b[39m\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toHaveCSS\" locator('.art-layer-lock').locator('.art-icon-lock') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-layer-lock').locator('.art-icon-lock')\u001b[22m\n\u001b[2m 18 × locator resolved to …\u001b[22m\n\u001b[2m - unexpected value \"none\"\u001b[22m\n\n\n 118 | const lock = page.locator('.art-layer-lock')\n 119 | await expect(lock).toHaveAttribute('aria-pressed', 'true')\n> 120 | await expect(lock.locator('.art-icon-lock')).toHaveCSS('display', 'inline-flex')\n | ^\n 121 | await expect(lock.locator('.art-icon-unlock')).toHaveCSS('display', 'none')\n 122 | await lock.focus()\n 123 | await page.keyboard.press('Space')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-lock.spec.js:120:48" + ] + } + ] + }, + { + "name": "core23-lock-remount-computed-style", + "stats": { + "startTime": "2026-09-11T12:11:11.695Z", + "duration": 112394.586, + "expected": 303, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "f94af777da4741f6b809b7e4642e1088dfe8d318c760d6b7b2e23f070f322734", + "failures": [ + { + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoHaveCSS\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-layer-lock').locator('.art-icon-lock')\nExpected: \u001b[32m\"\u001b[7minline-\u001b[27mflex\"\u001b[39m\nReceived: \u001b[31m\"flex\"\u001b[39m\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toHaveCSS\" locator('.art-layer-lock').locator('.art-icon-lock') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-layer-lock').locator('.art-icon-lock')\u001b[22m\n\u001b[2m 18 × locator resolved to …\u001b[22m\n\u001b[2m - unexpected value \"flex\"\u001b[22m\n\n\n 118 | const lock = page.locator('.art-layer-lock')\n 119 | await expect(lock).toHaveAttribute('aria-pressed', 'true')\n> 120 | await expect(lock.locator('.art-icon-lock')).toHaveCSS('display', 'inline-flex')\n | ^\n 121 | await expect(lock.locator('.art-icon-unlock')).toHaveCSS('display', 'none')\n 122 | await lock.focus()\n 123 | await page.keyboard.press('Space')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-lock.spec.js:120:48" + ] + }, + { + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "firefox", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoHaveCSS\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-layer-lock').locator('.art-icon-lock')\nExpected: \u001b[32m\"\u001b[7minline-\u001b[27mflex\"\u001b[39m\nReceived: \u001b[31m\"flex\"\u001b[39m\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toHaveCSS\" locator('.art-layer-lock').locator('.art-icon-lock') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-layer-lock').locator('.art-icon-lock')\u001b[22m\n\u001b[2m 17 × locator resolved to …\u001b[22m\n\u001b[2m - unexpected value \"flex\"\u001b[22m\n\n\n 118 | const lock = page.locator('.art-layer-lock')\n 119 | await expect(lock).toHaveAttribute('aria-pressed', 'true')\n> 120 | await expect(lock.locator('.art-icon-lock')).toHaveCSS('display', 'inline-flex')\n | ^\n 121 | await expect(lock.locator('.art-icon-unlock')).toHaveCSS('display', 'none')\n 122 | await lock.focus()\n 123 | await page.keyboard.press('Space')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-lock.spec.js:120:48" + ] + }, + { + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "webkit", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoHaveCSS\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-layer-lock').locator('.art-icon-lock')\nExpected: \u001b[32m\"\u001b[7minline-\u001b[27mflex\"\u001b[39m\nReceived: \u001b[31m\"flex\"\u001b[39m\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toHaveCSS\" locator('.art-layer-lock').locator('.art-icon-lock') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-layer-lock').locator('.art-icon-lock')\u001b[22m\n\u001b[2m 17 × locator resolved to …\u001b[22m\n\u001b[2m - unexpected value \"flex\"\u001b[22m\n\n\n 118 | const lock = page.locator('.art-layer-lock')\n 119 | await expect(lock).toHaveAttribute('aria-pressed', 'true')\n> 120 | await expect(lock.locator('.art-icon-lock')).toHaveCSS('display', 'inline-flex')\n | ^\n 121 | await expect(lock.locator('.art-icon-unlock')).toHaveCSS('display', 'none')\n 122 | await lock.focus()\n 123 | await page.keyboard.press('Space')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-lock.spec.js:120:48" + ] + } + ] + } + ], + "validationNotes": [ + "After full CI, only the remount browser assertion was corrected: inline-flex becomes computed flex inside a flex container. The test now verifies visibility and exact inline display, then retains single-unlock and cleanup assertions. Focused ESLint passed.", + "The first lock Tab test assumed an appended Outside button was next; the real fixture has Play/Pause controls before it. The corrected assertion checks the actual next external Play button and Shift+Tab back to Lock.", + "Strict typing retained the optional SSR info wrapper instead of asserting it non-null; published and candidate runtime tests verify that missing wrapper does not prevent the existing poll/close path." + ], + "remaining": [ + "CORE-23 remains doing and BASE-DOM-01 open. No completed-task commit.", + "Remaining mode exits, whole-player cross-instance/SSR/subtitle accessibility and final core acceptance still need work.", + "Info/lock includes optional SSR wrapper and absent native inert checks. Mobile user-agent selection does not prove physical-device or assistive-technology behavior.", + "This is a Vite source build. Fresh installed modern/legacy artifacts and the full current browser matrix remain task-final gates.", + "Physical devices, screen readers and release reviews remain gates. No push, tag, merge or npm publication." + ] +} diff --git a/refactor/baselines/keyboard-mini-partial.json b/refactor/baselines/keyboard-mini-partial.json new file mode 100644 index 000000000..eeb3bdc4a --- /dev/null +++ b/refactor/baselines/keyboard-mini-partial.json @@ -0,0 +1,1893 @@ +{ + "task": "CORE-23", + "status": "partial-mini", + "capturedAt": "2026-09-11T11:52:09.785Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "source": { + "packages/artplayer/src/accessibility/button.ts": "e5afa7aade56116082f54678c44961157950fa550d66e21a4e1ff9bb5369a6f8", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/accessibility/moved-focus.ts": "c3d2a7d496381b2a86819b82fbd26cc940a1204fdf19408ccc8db267741d96c9", + "packages/artplayer/src/accessibility/player-focus.ts": "e8fd5222cbfc38cd4938324c83d9f5cef3d01a439464e1570d63a5131c84f20a", + "packages/artplayer/src/accessibility/slider.ts": "533d5e6d806c32a84a578b43ed50993d30b4a414b5a85a34bbc68c37c5673a44", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/focus.ts": "91b085394e8a70164cee4de9fd454b081d309e21528d9c2cb065a09a2e4f911c", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "a25464e14216b2be392fcb3fdda2439e6d6f98d1962f0acbba30e3bd53bcb2d4", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "42c192d23e347d74e0bb814697a4d59eac20afbec102a282d5aa15780cab5f72", + "packages/artplayer/src/contextmenu/index.ts": "4fd292a931b5bda9f16a1c2bedd50cd0d8c0b8fb6010ffc5faaad2c197d2d9e5", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/playbackRate.ts": "e177f4017ea9291794fb4023715c81bfc01f927324ab9bd0e32c741e4a3b0ca7", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "629c622864619e2515b2eacb1bdfcf523ccce7ce680c8fdf51812e8e50a0cc7e", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/keyboard.ts": "03d1d47e6641ea08f765d731f10a6aad35f7c3edc16aa97df822c5f9a7f75eb0", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector-keyboard.ts": "6a749f48b23cda62148298e648bb380a6067cc18c7be4258b9ec85c382a56165", + "packages/artplayer/src/control/selector.ts": "a6f0c564c674530da9a0e4ed8762c6dfb81fa89373d64313e1020550731441f6", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "a03d6810ce078d358d4a8d1db8ce1246bc59c8429dcdeb0640766a29719df08f", + "packages/artplayer/src/control/volume.ts": "45474d8d7f43d59263aa42e774eaaafeb45530ec24b81a5f589f6c906954568b", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-focus.ts": "9a6b8280e8a443c87479a5806d1c85c2794038c38abc6f7ac8b85b63dc11086a", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "bbe69e4419ffc0f6c744cb730a51778f23c311a0fac157223bcf8d8bf0f3edc7", + "packages/artplayer/src/display/mini.ts": "a6fed598428bbf8d52931f21bb68b7560a3643d2576f7e7bfbae98b2f7cdd1e5", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "e88c868fd370fcc9dc612489992d446a8d0558bd87c26c5c05fdd73d8a3d1b02", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "bc091e6dcfb28784dd40ea619ce1fb9061b9e85dcc5bf2b6a303679eee5c727d", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "1619066eace6d660be3266bc32f650b75bb09ab880269fd44f4037527583a834", + "packages/artplayer/src/i18n/cs.ts": "472403884eaf0fc10680c66f85e051d51c0efb34afe5e4876b157b5ca7594534", + "packages/artplayer/src/i18n/es.ts": "23a1b5647f031de45cf1c36243327cc64a740856101c2d45324c25e53698b207", + "packages/artplayer/src/i18n/fa.ts": "9d15b2217a49d8ccb9abfbb469d136cd7db9130eccad18ae3f2004e53c72541b", + "packages/artplayer/src/i18n/fr.ts": "a43e3d24ad4a5dca54d427c0db0c3c5278ed1798774546e1ce229a7e5cdcc713", + "packages/artplayer/src/i18n/id.ts": "c80af1d4d5e7b84e96634b3833949325dde7f136853ae3a57e112adec6187d58", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "c0ad26fdf7d94f10f032e22c7179303b1f229da9207cb4158838b6260bc38363", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "93b91342ba9a1f6aaa75fa991836dd8afc80616f0b2a4ab9c6e573b96645944b", + "packages/artplayer/src/i18n/tr.ts": "aeff1411c07be47a6dcd54716919cc06816538f31b809c912f95592132d91ec7", + "packages/artplayer/src/i18n/vi.ts": "1fd82ae49adea148885a8049fb9c2a05574da6778e8d83ae669b6667bde913f1", + "packages/artplayer/src/i18n/zh-cn.ts": "2dc774985b8d06091fdb2a21704ff400a36a1be80d6c3e1c41d1cdd173bd21c4", + "packages/artplayer/src/i18n/zh-tw.ts": "2e68092b3bc587a7b4e7a5a7597e46798af07e56dcc4eb69c5cb6ae9f6c1830c", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/poll.ts": "1d7a519dd1960c8cd5fb7a020d8d3dbcd2eb272b612d823f2167997751aaf663", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock.ts": "9a08cec3a92006be8a9d2dba8d850bc4f8f38d586a50de86d725d0d8929130fd", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f6319af15ebe3600a466123dd9d343b86a8d6ed201693ac7ac86dc1d674d477f", + "packages/artplayer/src/setting/keyboard-focus.ts": "2717ce081f9bace0af287759571aadaab7e95c4be3b109a3168311a439b7d158", + "packages/artplayer/src/setting/keyboard-item.ts": "d94bfc0266486615ddb79b9eee3886f48891ebb2e5f465652ef98f142ada89d2", + "packages/artplayer/src/setting/keyboard.ts": "14781e4308b2ea7043314e88fb40f379a3dcfb4c97f10508b96b3455a05c3286", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "ed73745f2c7e2d76bbe8ce7202336e5f4de217dc8f0806b769127cb25316faba", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a642e630924eaf4ad91705fad1fa6e6dc946b32970d809a23da274399fce20ef", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "21a07d75a28bbbe20b3e107b6f1a09cb6f8ef2773ea10a4bd7caa88956e9b99c", + "packages/artplayer/src/setting/update.ts": "79326cb55c52243a7aa8df347a3b081dcd84eb7932fc6162061cc0d9f7078add", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "da98a47e8419b33069191e51fc94cc9652302ee4f3eff8ccc7a6dbd4c4c0e2bc", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "2da8fcde7d38ca29cd1e42cd57ab0b0d47fde2a2866bbd33223f5c8e459472b5", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "8be782a3054154ab908b1cce650b6131330cf0f0e936b749accb4b2dfe605a27", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "589d05e12a62e04fe848b36ba748433d23f0b909a04e861b1d6737f2799be183", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "44585c6b0179e34d21eeefce6d3494faacc0e9d108079426876e8847fd441513", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "6e99bbe0dbcb40667ef99789b65812dc9c94ce8a1071c00d2edec5eba041c434", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "8f82a43a5871a1b595d145831f1993755f114a74865faf2f2761b41bb4164c4a", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "tooling": { + "package.json": "315746ada69ccb62b8b8c10016b3e467667db9e39518b32dc8036cbade662ea4", + "test/browser/accessibility-controls.spec.js": "d07d9919b9e9d960116770f82ebb61d165bd4b9fbc343a4e821d9cf9313dccef", + "test/browser/accessibility-mini.spec.js": "a0d667265145ff24e37624775ae388f184ad425c4844c47ce8c692de31123a32", + "test/browser/accessibility-selector.spec.js": "aae91d2449e2257bfd19999505cf0bb5c631bd49b0dbf597ea1ac48e2f2a25d1", + "test/browser/accessibility-setting.spec.js": "067ace54bf2f73daed4d26c005daaaba09f292f7474825070f2dfbc0c50b544b", + "test/browser/accessibility-slider.spec.js": "b88aa23fc1b76e3a902150a8a9d4a801531f397b0a27120b4741baf67f82bc47", + "test/browser/accessibility.spec.js": "f10bdefdaac2359d1af5d2099cb8e1770bd7ca486362143f663b5c54459d6cab", + "test/browser/display-mini.spec.js": "eecb351ef6c1b4d5a96c682e9d9b4507260473b10159bad0b918af277c2c58f3", + "test/browser/display-web.spec.js": "50bdbbb4988e47e34a4cbb08184a68b0000e2dcf34bf60192267648045b3aca0", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c" + }, + "ci": { + "passed": 468, + "productionTypeScript": 242, + "logSha256": "62c6bddc749b5aa991945d0d5a1d5df5352da484f53333a7eeb69c18245c4d3a" + }, + "browser": { + "stats": { + "startTime": "2026-09-11T11:50:01.022Z", + "duration": 101091.55, + "expected": 300, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "c2e3efc5d08dd7cca954346d7f45079556705e4abcf245ef1bfed8d50646af3e", + "cases": [ + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "chromium" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "firefox" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "webkit" + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "chromium" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "firefox" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "webkit" + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "webkit" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + } + ], + "reportSha256": "8ec665945669526bbad1ffea3f2e645b1bfe2136d346e4d2e031a8c55808d302" + }, + "probes": [ + { + "name": "core23-mini-keyboard-before", + "stats": { + "startTime": "2026-09-11T11:45:51.339Z", + "duration": 11118.185, + "expected": 0, + "skipped": 0, + "unexpected": 4, + "flaky": 0 + }, + "reportSha256": "012662fa38913af8aebddbba531fcdbfb33c7f2eef6ac08388b41d69d4e2c82a", + "failures": [ + { + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-mini-popup').locator('.art-mini-close')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-mini-popup').locator('.art-mini-close') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-mini-popup').locator('.art-mini-close')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 30 | await page.keyboard.press('Enter')\n 31 | const popup = page.locator('.art-mini-popup')\n> 32 | await expect(popup.locator('.art-mini-close')).toBeFocused()\n | ^\n 33 | await expect(popup.locator('.art-mini-close')).toHaveAttribute('aria-label', 'Close')\n 34 | await page.keyboard.press('Tab')\n 35 | await expect(popup.locator('.art-mini-state')).toBeFocused()\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-mini.spec.js:32:50" + ] + }, + { + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeHidden\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-mini-popup')\nExpected: hidden\nReceived: visible\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeHidden\" locator('.art-mini-popup') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-mini-popup')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"visible\"\u001b[22m\n\n\n 55 | await page.locator('.art-mini-close').focus()\n 56 | await page.keyboard.press('Space')\n> 57 | await expect(page.locator('.art-mini-popup')).toBeHidden()\n | ^\n 58 | await expect(page.locator('.art-control-mini-trigger')).toBeFocused()\n 59 | expect(await page.evaluate(() => window.miniCalls)).toEqual([['mini', true], ['mini', false]])\n 60 | })\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-mini.spec.js:57:49" + ] + }, + { + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-video-player')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-video-player') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-video-player')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 71 | await page.evaluate(() => window.art.controls.remove('mini-trigger'))\n 72 | await page.keyboard.press('Escape')\n> 73 | await expect(page.locator('.art-video-player')).toBeFocused()\n | ^\n 74 | await expect(page.locator('.art-mini-popup')).toBeHidden()\n 75 | })\n 76 |\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-mini.spec.js:73:51" + ] + }, + { + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mtrue\u001b[39m\nReceived: \u001b[31mfalse\u001b[39m\n\n 85 | })\n 86 | await page.keyboard.press('Escape')\n> 87 | expect(await page.evaluate(() => window.art.isDestroy)).toBe(true)\n | ^\n 88 | await page.evaluate(() => {\n 89 | window.retainedMini.querySelector('.art-mini-close').click()\n 90 | window.retainedMini.querySelector('.art-icon-play').click()\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-mini.spec.js:87:59" + ] + } + ] + } + ], + "remaining": [ + "CORE-23 remains doing and BASE-DOM-01 open. No completed-task commit.", + "Remaining info/lock keyboard affordances and mode exit, SSR/subtitle accessibility and whole-core acceptance still need work.", + "Owned mini controls and focus are covered; caller-owned popup controls remain caller-managed and remaining whole-player cross-instance checks are still required.", + "This is a Vite source build. Fresh installed modern/legacy artifacts and the full current browser matrix remain task-final gates.", + "Physical devices, screen readers and release reviews remain gates. No push, tag, merge or npm publication." + ] +} diff --git a/refactor/baselines/keyboard-selectors-partial.json b/refactor/baselines/keyboard-selectors-partial.json new file mode 100644 index 000000000..dd041f81f --- /dev/null +++ b/refactor/baselines/keyboard-selectors-partial.json @@ -0,0 +1,2066 @@ +{ + "task": "CORE-23", + "status": "partial-selectors", + "capturedAt": "2026-09-11T10:57:11.207Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "source": { + "packages/artplayer/src/accessibility/button.ts": "f6f67e19bbee2f1fa6a82828c451bcb86b5b1062575de411a0e72313a38c1c06", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/accessibility/slider.ts": "533d5e6d806c32a84a578b43ed50993d30b4a414b5a85a34bbc68c37c5673a44", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "a25464e14216b2be392fcb3fdda2439e6d6f98d1962f0acbba30e3bd53bcb2d4", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "42c192d23e347d74e0bb814697a4d59eac20afbec102a282d5aa15780cab5f72", + "packages/artplayer/src/contextmenu/index.ts": "4fd292a931b5bda9f16a1c2bedd50cd0d8c0b8fb6010ffc5faaad2c197d2d9e5", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/playbackRate.ts": "e177f4017ea9291794fb4023715c81bfc01f927324ab9bd0e32c741e4a3b0ca7", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "629c622864619e2515b2eacb1bdfcf523ccce7ce680c8fdf51812e8e50a0cc7e", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/keyboard.ts": "2e07680ce71ede06d6ba63cfc2c4a81a00dda5aab3daea1844552603a881f0ad", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector-keyboard.ts": "6a749f48b23cda62148298e648bb380a6067cc18c7be4258b9ec85c382a56165", + "packages/artplayer/src/control/selector.ts": "a6f0c564c674530da9a0e4ed8762c6dfb81fa89373d64313e1020550731441f6", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "f82b0d645026121265cc8d780841a71ca5caad79ccec3765d7f03fc8aad3f17a", + "packages/artplayer/src/control/volume.ts": "45474d8d7f43d59263aa42e774eaaafeb45530ec24b81a5f589f6c906954568b", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "83a6e5c6d1923332973009b7ac1561f7a55fb72e5c60e5ebc88af1fa4b641d5e", + "packages/artplayer/src/display/mini.ts": "3ffae49b1407523da2dc5f2bc687018268f6c1d1d3c71911dd4aa96d1a66c1dc", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "6f78b34b903fb30653cc7169f43861f8be426d1f6e9669ef292e41a1606d685c", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "dd2c5cf65cfe35d6b5a87d01acb28f48119b27fe6e5f0c6a8b9bab3db1a1923f", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "f224dcd83c4ca5a1a862a91a418faa7d5e0ee9762408ee70f332aa44c8f59861", + "packages/artplayer/src/i18n/cs.ts": "6d39bb19b20080a5960b6fa0fdb0b9b031ed5a72a609a9c15b9624d3868399fb", + "packages/artplayer/src/i18n/es.ts": "b6fafd2309515439c033f61060d1d717d2becced6ef4b9c733162287f8218d8a", + "packages/artplayer/src/i18n/fa.ts": "27ffb3d154f30f592aa2df9193acc5bcdd11aed99d6fe4dd6117fe3f365df59a", + "packages/artplayer/src/i18n/fr.ts": "eef378e4ca959983fddd24f435441344026480c9c5878fd9d2f360e11ca37f4b", + "packages/artplayer/src/i18n/id.ts": "dfb6bb205a721014fe4ee1e27e78d9df91b8286f17bc336e7400258de64d60e3", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "552cebb3685f5eb98eff0d30d947a84e58460cba2f920f34d8be8b6ad44e7b0a", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "502595795c428f4b86bd3a8e86a87e54c77d0303c5cd86ea5d259f17ce400874", + "packages/artplayer/src/i18n/tr.ts": "9821f4652f56593c68110ddca34d9ed0616f1336267f17a33f01fdb5bd1e1e54", + "packages/artplayer/src/i18n/vi.ts": "4853b1c1fe1aca410c739a2017c3715fbcaaec2be47f3f0396f8ffb10be84987", + "packages/artplayer/src/i18n/zh-cn.ts": "81454382b97c0d2fa94128dd7e94c8089f13d16bc2dd9cacc58a88b7ddc9a130", + "packages/artplayer/src/i18n/zh-tw.ts": "22b7cdd27c117807f3990d3eab63cb09427bc79f1edf20356a2849cc45b5d450", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/poll.ts": "1d7a519dd1960c8cd5fb7a020d8d3dbcd2eb272b612d823f2167997751aaf663", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock.ts": "9a08cec3a92006be8a9d2dba8d850bc4f8f38d586a50de86d725d0d8929130fd", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f1e8a302077a8ccfa77c17ce344bdd6816943e77b5876c7f623314ff846742f7", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "853090bfffe579c5106124d64c8d2a646876448bcc7258740a96820d56508ad0", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a1bc04b99bda45cc1a2afcf2dd0925c88ccb55e169b971105277883ae2ccba0c", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "08298ce2c04b5c909b3cc9b1071d2e3e91a7096ba878165a55073e20c33321b0", + "packages/artplayer/src/setting/update.ts": "949c0001e9ae10c08ad9a9fce1c88603d98a9cb9b7ac5fa6620ee00a07933187", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "35d3fabf5415606a0bcf4c5f6c519d8b005a63ce1f1aeef67c75d0b37925266d", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "2da8fcde7d38ca29cd1e42cd57ab0b0d47fde2a2866bbd33223f5c8e459472b5", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "927fd6c6c5ab440a2b25ecc43211ab89106c739385385b62de3880ed45dd7601", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "589d05e12a62e04fe848b36ba748433d23f0b909a04e861b1d6737f2799be183", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "44585c6b0179e34d21eeefce6d3494faacc0e9d108079426876e8847fd441513", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "6e99bbe0dbcb40667ef99789b65812dc9c94ce8a1071c00d2edec5eba041c434", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "659b92428f54a64b7c1bbc8743c09b573b21c28080cbeb4d371293262a46c608", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "tooling": { + "package.json": "315746ada69ccb62b8b8c10016b3e467667db9e39518b32dc8036cbade662ea4", + "test/browser/accessibility-selector.spec.js": "aae91d2449e2257bfd19999505cf0bb5c631bd49b0dbf597ea1ac48e2f2a25d1", + "test/browser/accessibility-slider.spec.js": "1a75012aae760cd1e3a2344786b3d7a5c80099f577e7e76235e7bc908fcbf9e3", + "test/browser/accessibility.spec.js": "f10bdefdaac2359d1af5d2099cb8e1770bd7ca486362143f663b5c54459d6cab", + "test/browser/components.spec.js": "2be381b052b69baa3b4ae9cf2582593b9d611158e709e056aaa5df3cf969bef4", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c", + "test/browser/progress-quality.spec.js": "824596e3f0f1a7d8304ca7fed38de4f00b2f967eb87fd48346ad714fbb2e280f", + "test/browser/prompt-components.spec.js": "2513a31306bb17b713aca2f9bc44f045ce34ac547482b4507955b0f1f14484ed" + }, + "ci": { + "passed": 463, + "productionTypeScript": 235, + "logSha256": "e9a83dd13102be340e857ae8aafd68cbc9791df8760fdb3a028d952141dbd49c" + }, + "browser": { + "stats": { + "startTime": "2026-09-11T10:54:04.786Z", + "duration": 93083.624, + "expected": 282, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "7e449d4d94aeded6be17d5f1c59445327a3f398822beaca836e99a0a4f39ec96", + "cases": [ + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "passed": true + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "chromium", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "firefox", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "webkit", + "passed": true + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "webkit", + "passed": true + } + ], + "screenshots": { + "refactor/.cache/core23-selector-keyboard-chromium.png": "cffa97ce62c1db68020f2f4e4567ec3d8308bc85a3b9e55d3488a7150ba75cc2", + "refactor/.cache/core23-selector-keyboard-firefox.png": "e0a8dd37cb8429b44868deb3cbe1759ca00f36b14d68ee739921b1be482d62ba", + "refactor/.cache/core23-selector-keyboard-webkit.png": "d88be3ad1ba84622e6b46a32aa7055a3b76090d17be1364a299e716f696b3d24" + }, + "reportSha256": "72b84943b54584a6a0172dbd79d4bc94b55e9bb7ba56193649e3c085cde46be3" + }, + "probes": [ + { + "name": "core23-selector-edge-before", + "stats": { + "startTime": "2026-09-11T10:53:05.491Z", + "duration": 10476.812, + "expected": 0, + "skipped": 0, + "unexpected": 2, + "flaky": 0 + }, + "reportSha256": "fd7ef4c50d19161cd98ca299c4891b86b5217a8d0466a27b784de1916c36348f", + "failures": [ + { + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mfalse\u001b[39m\nReceived: \u001b[31mtrue\u001b[39m\n\nCall Log:\n- Timeout 7000ms exceeded while waiting on the predicate\n\n 242 | expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(true)\n 243 | await page.keyboard.press('Escape')\n> 244 | await expect.poll(() => page.evaluate(() => window.art.fullscreenWeb)).toBe(false)\n | ^\n 245 | })\n 246 |\n 247 | test('candidate: hovering an empty selector does not announce an expanded popup', async ({ page }) => {\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-selector.spec.js:244:74" + ] + }, + { + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoHaveAttribute\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-keyboard-selector .art-selector-value')\nExpected: \u001b[32m\"\u001b[7mfals\u001b[27me\"\u001b[39m\nReceived: \u001b[31m\"\u001b[7mtru\u001b[27me\"\u001b[39m\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toHaveAttribute\" locator('.art-control-keyboard-selector .art-selector-value') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-keyboard-selector .art-selector-value')\u001b[22m\n\u001b[2m 18 × locator resolved to
Bravo
\u001b[22m\n\u001b[2m - unexpected value \"true\"\u001b[22m\n\n\n 248 | await setup(page, 'empty')\n 249 | await trigger(page).hover()\n> 250 | await expect(trigger(page)).toHaveAttribute('aria-expanded', 'false')\n | ^\n 251 | await expect(trigger(page)).toHaveAttribute('aria-disabled', 'true')\n 252 | })\n 253 |\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-selector.spec.js:250:31" + ] + } + ] + } + ], + "remaining": [ + "CORE-23 remains doing and BASE-DOM-01 remains open; no completed-task commit.", + "Settings tree, mode exit, dynamic control removal/replacement focus, multi-instance/SSR and subtitle accessibility still need implementation/audit.", + "The browser suite uses a source build, not freshly packed modern/legacy artifacts or the full browser matrix.", + "Physical devices and screen-reader evidence remain release gates; no npm publication, push, tag or merge." + ] +} diff --git a/refactor/baselines/keyboard-settings-partial.json b/refactor/baselines/keyboard-settings-partial.json new file mode 100644 index 000000000..b5f6c4d67 --- /dev/null +++ b/refactor/baselines/keyboard-settings-partial.json @@ -0,0 +1,3320 @@ +{ + "task": "CORE-23", + "status": "partial-settings", + "capturedAt": "2026-09-11T11:31:58.144Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "source": { + "packages/artplayer/src/accessibility/button.ts": "e5afa7aade56116082f54678c44961157950fa550d66e21a4e1ff9bb5369a6f8", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/accessibility/moved-focus.ts": "c3d2a7d496381b2a86819b82fbd26cc940a1204fdf19408ccc8db267741d96c9", + "packages/artplayer/src/accessibility/slider.ts": "533d5e6d806c32a84a578b43ed50993d30b4a414b5a85a34bbc68c37c5673a44", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "a25464e14216b2be392fcb3fdda2439e6d6f98d1962f0acbba30e3bd53bcb2d4", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "42c192d23e347d74e0bb814697a4d59eac20afbec102a282d5aa15780cab5f72", + "packages/artplayer/src/contextmenu/index.ts": "4fd292a931b5bda9f16a1c2bedd50cd0d8c0b8fb6010ffc5faaad2c197d2d9e5", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/playbackRate.ts": "e177f4017ea9291794fb4023715c81bfc01f927324ab9bd0e32c741e4a3b0ca7", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "629c622864619e2515b2eacb1bdfcf523ccce7ce680c8fdf51812e8e50a0cc7e", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/keyboard.ts": "03d1d47e6641ea08f765d731f10a6aad35f7c3edc16aa97df822c5f9a7f75eb0", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector-keyboard.ts": "6a749f48b23cda62148298e648bb380a6067cc18c7be4258b9ec85c382a56165", + "packages/artplayer/src/control/selector.ts": "a6f0c564c674530da9a0e4ed8762c6dfb81fa89373d64313e1020550731441f6", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "a03d6810ce078d358d4a8d1db8ce1246bc59c8429dcdeb0640766a29719df08f", + "packages/artplayer/src/control/volume.ts": "45474d8d7f43d59263aa42e774eaaafeb45530ec24b81a5f589f6c906954568b", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "83a6e5c6d1923332973009b7ac1561f7a55fb72e5c60e5ebc88af1fa4b641d5e", + "packages/artplayer/src/display/mini.ts": "3ffae49b1407523da2dc5f2bc687018268f6c1d1d3c71911dd4aa96d1a66c1dc", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "6f78b34b903fb30653cc7169f43861f8be426d1f6e9669ef292e41a1606d685c", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "bc091e6dcfb28784dd40ea619ce1fb9061b9e85dcc5bf2b6a303679eee5c727d", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "1619066eace6d660be3266bc32f650b75bb09ab880269fd44f4037527583a834", + "packages/artplayer/src/i18n/cs.ts": "472403884eaf0fc10680c66f85e051d51c0efb34afe5e4876b157b5ca7594534", + "packages/artplayer/src/i18n/es.ts": "23a1b5647f031de45cf1c36243327cc64a740856101c2d45324c25e53698b207", + "packages/artplayer/src/i18n/fa.ts": "9d15b2217a49d8ccb9abfbb469d136cd7db9130eccad18ae3f2004e53c72541b", + "packages/artplayer/src/i18n/fr.ts": "a43e3d24ad4a5dca54d427c0db0c3c5278ed1798774546e1ce229a7e5cdcc713", + "packages/artplayer/src/i18n/id.ts": "c80af1d4d5e7b84e96634b3833949325dde7f136853ae3a57e112adec6187d58", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "c0ad26fdf7d94f10f032e22c7179303b1f229da9207cb4158838b6260bc38363", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "93b91342ba9a1f6aaa75fa991836dd8afc80616f0b2a4ab9c6e573b96645944b", + "packages/artplayer/src/i18n/tr.ts": "aeff1411c07be47a6dcd54716919cc06816538f31b809c912f95592132d91ec7", + "packages/artplayer/src/i18n/vi.ts": "1fd82ae49adea148885a8049fb9c2a05574da6778e8d83ae669b6667bde913f1", + "packages/artplayer/src/i18n/zh-cn.ts": "2dc774985b8d06091fdb2a21704ff400a36a1be80d6c3e1c41d1cdd173bd21c4", + "packages/artplayer/src/i18n/zh-tw.ts": "2e68092b3bc587a7b4e7a5a7597e46798af07e56dcc4eb69c5cb6ae9f6c1830c", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/poll.ts": "1d7a519dd1960c8cd5fb7a020d8d3dbcd2eb272b612d823f2167997751aaf663", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock.ts": "9a08cec3a92006be8a9d2dba8d850bc4f8f38d586a50de86d725d0d8929130fd", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f6319af15ebe3600a466123dd9d343b86a8d6ed201693ac7ac86dc1d674d477f", + "packages/artplayer/src/setting/keyboard-focus.ts": "2717ce081f9bace0af287759571aadaab7e95c4be3b109a3168311a439b7d158", + "packages/artplayer/src/setting/keyboard-item.ts": "d94bfc0266486615ddb79b9eee3886f48891ebb2e5f465652ef98f142ada89d2", + "packages/artplayer/src/setting/keyboard.ts": "14781e4308b2ea7043314e88fb40f379a3dcfb4c97f10508b96b3455a05c3286", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "ed73745f2c7e2d76bbe8ce7202336e5f4de217dc8f0806b769127cb25316faba", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a642e630924eaf4ad91705fad1fa6e6dc946b32970d809a23da274399fce20ef", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "21a07d75a28bbbe20b3e107b6f1a09cb6f8ef2773ea10a4bd7caa88956e9b99c", + "packages/artplayer/src/setting/update.ts": "79326cb55c52243a7aa8df347a3b081dcd84eb7932fc6162061cc0d9f7078add", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "da98a47e8419b33069191e51fc94cc9652302ee4f3eff8ccc7a6dbd4c4c0e2bc", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "2da8fcde7d38ca29cd1e42cd57ab0b0d47fde2a2866bbd33223f5c8e459472b5", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "927fd6c6c5ab440a2b25ecc43211ab89106c739385385b62de3880ed45dd7601", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "589d05e12a62e04fe848b36ba748433d23f0b909a04e861b1d6737f2799be183", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "44585c6b0179e34d21eeefce6d3494faacc0e9d108079426876e8847fd441513", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "6e99bbe0dbcb40667ef99789b65812dc9c94ce8a1071c00d2edec5eba041c434", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "659b92428f54a64b7c1bbc8743c09b573b21c28080cbeb4d371293262a46c608", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "publicTypes": { + "docs/assets/ts/artplayer.d.ts": "e3bf065a5131946f328d7e3062ec595e47d4c02b13cbff8f06adfc72d2d2dec1", + "packages/artplayer/public/artplayer.cts": "0e91e907d021db02a68004603e6190505fdc0806d873ebb6af171aa089a81da7", + "packages/artplayer/public/artplayer.mts": "f6292596a9ccb1d43a6d6a12c35f859b1889ad15924c5ae0f9f280941aade313", + "packages/artplayer/public/artplayer.ts": "26a42ac66811e70f68a8ebe62cbf304eb1993451b3e658961be98e7106162527", + "packages/artplayer/public/component.ts": "aa1c43be67322781b4b355b143bc69d9f29d22e578e4974d6a13e957a7c0334f", + "packages/artplayer/public/config.ts": "c4fd8681bf32b10c743e3e561c532520c8f32e43fd765524850b15e55cb91c72", + "packages/artplayer/public/cssVar.ts": "e027d82fb4f01c9ce7559cf679b2d5ee1962d3f7e5b4dd64ca21f472b933efb6", + "packages/artplayer/public/emitter.ts": "9c62551cdcc6dd3966bed8a7a85dd477435db977c91a294d2ac8f162f9592537", + "packages/artplayer/public/events.ts": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "packages/artplayer/public/i18n.ts": "754e7466361dde1193969e2ef7c0fe9a9cc7fe1e44aa6e40ba98ef6ddd2abeb1", + "packages/artplayer/public/icons.ts": "0d8e8e52e52130dd4a29bab551dd7a2a954797e42e92a6e068c85d583e23e6a4", + "packages/artplayer/public/language.cts": "2248040d86a8e34626755c4ecf53ea0174706c653073cf0e15884a030d173120", + "packages/artplayer/public/language.mts": "c391e863012c77769e661afbf8fa949e9373aa88d17f58cbba7f5696edb8077f", + "packages/artplayer/public/legacy/language.ts": "c452ffd764ff9b29b819b3475c42395d2ea7a33560d8c186ef5df3844b9524c3", + "packages/artplayer/public/option.ts": "850e5264219b8b438c80694402225b690b131786677a5da0d22739ec2352d263", + "packages/artplayer/public/playback.ts": "1ceaed3aa1cef511fe8b20f4874647f6065c723ad805b742a0a9247e16bb1bb5", + "packages/artplayer/public/player.ts": "f1e50257df2ea592d0a0e1f36078dda77eaf2cf3b3d795307501396562d99f28", + "packages/artplayer/public/plugin.ts": "2a57e148fda00ee687da5036b890b0f611cb94bb403a1ed52602179060259d35", + "packages/artplayer/public/quality.ts": "7ed6ed78cea52991b2f6ddd2bd3b7bd8c5146fdfff7486fe8b814c3e632f1567", + "packages/artplayer/public/runtime.cts": "52cfff1daeb6841a90212c8fa8d46ca46d6650bb7ed1b59b62115d854b8ad652", + "packages/artplayer/public/runtime.mts": "1b09bc0ee0f0ee2f788689eaff441bdeda1fab0ce783e71b61b9792d81072b03", + "packages/artplayer/public/runtime.ts": "ec4b1d56993eb482a77eb0f94b701047549d009e6ba6433f27e7d464fef30c2b", + "packages/artplayer/public/runtime/component.ts": "840213299c942fe058eb5436977ceec066b9dccda24c55ae9f464b399c979e39", + "packages/artplayer/public/runtime/construction.ts": "24cc5cda1f614314db382271a9b0d5583b781894cfdf6c548700b1b5270467ee", + "packages/artplayer/public/runtime/events.ts": "52848f57d35eb1037cf74c8877521edf99a015bcd77f30ef6bbcba1807a99bfe", + "packages/artplayer/public/runtime/media.ts": "8828f80953aec3e95328cefe691661e8897cb27cb309483cf806ec45a8549ae3", + "packages/artplayer/public/runtime/option.ts": "bb672e49ffe74a6fc78543217f6de80d7d738890146df0857c709d4dc283e4ce", + "packages/artplayer/public/runtime/player.ts": "a4a24794e26cfb9e4310bf0f459a7a407e85bf81b4f3a4feb6294331af8036fb", + "packages/artplayer/public/runtime/plugin.ts": "9ad482f2a77914a91450419680b8af6b314b926f0831c2f7f6d7c466690f95c9", + "packages/artplayer/public/runtime/services.ts": "8e4648d8c61bff47343f9e1c2b995af69fc00947264b826109ceadcbaf553254", + "packages/artplayer/public/runtime/setting.ts": "c48d20957b57f79f985ef76a2950cc8a5cfa25dafa8ec5939e562661778e6218", + "packages/artplayer/public/runtime/subtitle.ts": "13241c4f9a87517aa2cf7b3e0bb8cedaa12fa0b4d3f8934285797583b752557e", + "packages/artplayer/public/runtime/template.ts": "da9975513a1938e7f386f4f65f718f0fc595164bfeac8f0cd99a3e97a54919a1", + "packages/artplayer/public/runtime/utils.ts": "cab9916f5224a3b047812b9f759cc9cc62105662599744067a6955020ab36916", + "packages/artplayer/public/setting.ts": "d12a75b656fff70cbb30be4bffec46d9c4273636e8722bce971a4d2b188712a1", + "packages/artplayer/public/subtitle.ts": "d25b470e47d6a9bd696d9c1ad8adb58e56a208f05695186d513bc8c43c2e8acf", + "packages/artplayer/public/template.ts": "68aed9e97d006d6be4fabb8504ca84dafab770b0925f4d6e7319e67c82f21b0d", + "packages/artplayer/public/utils.ts": "494ec447ab467a07ddd7a2c2abf778b3fce69fd28a09aaa8ced9759f8de2e3f6", + "packages/artplayer/types/COMPATIBILITY.md": "a7da9e102a116104b513df4f7451247b7759bc502d3375f30bd5b14a541826e0", + "packages/artplayer/types/README.md": "1bd9868e773610e6312fd48a1c5aa20772d29df0af40c3db66e75b7ab4a1aee0", + "packages/artplayer/types/artplayer.d.cts": "3685065e4263abcfd9d953176e461d5b3eb990b0363b54689a7f55deba770fef", + "packages/artplayer/types/artplayer.d.mts": "b664fec51ee5c5381f2ceab25d99d52aee56feab04a2ee7b4ea5b2145ea5fa0e", + "packages/artplayer/types/artplayer.d.ts": "5d0162adf7ac6d0f2bb9b5cfe361f28657c4d9c540cadbf36eba3cc954ce50f8", + "packages/artplayer/types/component.d.ts": "ae5bc1ddeaa1ee1ebbc62573e32423993727079205c64751a5a314170e588a32", + "packages/artplayer/types/config.d.ts": "36f9a84cd436f17701a0d11d3417fc1fe0414e0c52c80083b94a85dfc329e37e", + "packages/artplayer/types/cssVar.d.ts": "93217860fff2ebf750f606d95ddd22220a58837119e63bdf2f5f78fd7488458b", + "packages/artplayer/types/emitter.d.ts": "7e1f9a2a8ce65feb95734f1ed52d1334e57aa388bbef2a43d8bc53a9b6f6623c", + "packages/artplayer/types/events.d.ts": "f83624c9268a284477e8bd793fe3562a2363b72f2a44d5c64fe8c6a6cede8830", + "packages/artplayer/types/i18n.d.ts": "293d64cb9a78d069e8eab056fb1601ebe4d90c2cf8e2a8336b4754e09d798fde", + "packages/artplayer/types/icons.d.ts": "326a67ba7bdcf52862c5b2a269e540140aff98d05c7b96196485a77f84fe5960", + "packages/artplayer/types/language.d.cts": "f7928e108cf7b7814c2d75cb0a525333e95873fca6cd6d89a740450656b9c1cd", + "packages/artplayer/types/language.d.mts": "6619a26d604b7cccbe2f596243d87ae37cfaae33b8b52874ec071d9787446f9e", + "packages/artplayer/types/legacy/language.d.ts": "c7abda4d506fd933c350e9030290bf9e64347a921d683a66115da1995ebe0a81", + "packages/artplayer/types/option.d.ts": "ccf2c8ddc537dc65c9682d39f044726e23bff18f476b622512d7e6a4b949b5f6", + "packages/artplayer/types/playback.d.ts": "58705c273df6e76a77a6575e769a9ec6c013785c25080f2551aa22415788d870", + "packages/artplayer/types/player.d.ts": "92b00211b70ac71336e495899df972a0519dd138111846044fe4e0f967966177", + "packages/artplayer/types/plugin.d.ts": "fc3594a41c51d8248713e33c486fb1f6a518ac5c7ce31be6988a6cd8d052c5f3", + "packages/artplayer/types/quality.d.ts": "1ac1a48b4f74ff9ba1ce60443e1463d50d1c6a2e5d87d63dc7d2a8eb7f4c2c34", + "packages/artplayer/types/runtime.d.cts": "7ee988dfea9a0ac71a34a656f96f7b74e78aa92547cfdfab7ff7e1139a77d4a3", + "packages/artplayer/types/runtime.d.mts": "dcb85f59a8b7714918ced0c1d18c2bb24e8b80b56d8c594e019dcbdb5ad88b08", + "packages/artplayer/types/runtime.d.ts": "9c6ccd39a1be293f17ae46dae8ea077053e12635ee79d73a5e3b3a559230fcff", + "packages/artplayer/types/runtime/component.d.ts": "1b4c0cee44568649e80140fe778febfcae88af0ac85515f1cbeff78ab0c6d14f", + "packages/artplayer/types/runtime/construction.d.ts": "7a87bedf6f7ffff0c46078aa5f1551e0077d35574e286516121f5f935e2d9ce4", + "packages/artplayer/types/runtime/events.d.ts": "a1e2f9d387475453eaf95c2a5ee79e228636c0bb859bda3fcc46da46574a0c31", + "packages/artplayer/types/runtime/media.d.ts": "8fc89401be7fe25542c169d07dd5675f10916ed20be8493e19695966cf3864a8", + "packages/artplayer/types/runtime/option.d.ts": "6e334e1a76fdcc40b4665c02523bd31c3994d96078fadeb40e23422aa54c1a1d", + "packages/artplayer/types/runtime/player.d.ts": "8ac6383502e4872e83659838844856903031a81a0adc8e8535feb78453aa042c", + "packages/artplayer/types/runtime/plugin.d.ts": "8528f2b17843149f42f9cc16d6fd70baa238c9dc2c329b67d2c38096799c69bd", + "packages/artplayer/types/runtime/services.d.ts": "604c9f8e4b6c0da818f96576bf9f4b0e96085a9003927b2f7ba30027b1ba237e", + "packages/artplayer/types/runtime/setting.d.ts": "349c1fcb205ad312916bd3ee55e6bf241ea8a569fb2ab6c80822e69fc518f7d7", + "packages/artplayer/types/runtime/subtitle.d.ts": "269ff84678d327b3a9dc2f5bc6cc0d731d1e081b85422e474621d5d792efb153", + "packages/artplayer/types/runtime/template.d.ts": "7a62f968a38b4bf9109a4439557c02074eb1d62ba1f6e21a8eb194e91f0badfe", + "packages/artplayer/types/runtime/utils.d.ts": "6bf731705d86853e066dbaf3b8d4003b6548423fe615b7412b722bd0d3a6e48b", + "packages/artplayer/types/setting.d.ts": "08305a75dff96f06490430e099338b463df471b550c1d0dac3abc8995b39eb09", + "packages/artplayer/types/subtitle.d.ts": "b18314e2d64efdb6045830b6e12f615ae2ed585416130e562329ad3ea337f6ce", + "packages/artplayer/types/template.d.ts": "4792bc0c2cbcb7966e4375118bd34b326166e0831862e94ace4cf6b1bbe6a8c8", + "packages/artplayer/types/utils.d.ts": "fca0d3d814df94a25f9eb067c86fa0cf272e2791bac793b91229d57680797712" + }, + "tests": { + "package.json": "315746ada69ccb62b8b8c10016b3e467667db9e39518b32dc8036cbade662ea4", + "test/accessibility-button.test.js": "8def35ef049277d08fcc8389555a53b44273965e143ef91aac85b97f1c32c443", + "test/accessibility-focus.test.js": "1210380f832b0dc04b25031549581adf5b809d41a217aa562f53ece337318a11", + "test/accessibility-slider.test.js": "80238f1faa8f3fbe440e78613260b5cdf1e0dbd7b65738213749c5e8c90ddcee", + "test/browser/accessibility-setting.spec.js": "067ace54bf2f73daed4d26c005daaaba09f292f7474825070f2dfbc0c50b544b", + "test/browser/accessibility-slider.spec.js": "b88aa23fc1b76e3a902150a8a9d4a801531f397b0a27120b4741baf67f82bc47" + }, + "ci": { + "passed": 468, + "productionTypeScript": 239, + "logSha256": "736c28cc71d0f07d6b93c77d3a7f0c37eddd4916745a9bc2ee4c3501166bef0c" + }, + "browser": { + "broad": { + "stats": { + "startTime": "2026-09-11T11:26:41.851Z", + "duration": 128224.594, + "expected": 477, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "208bf80014234fdf1c689c955ad10b272e96dc452e90e07d257b140eddc66ec2", + "cases": [ + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "firefox" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "webkit" + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox" + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit" + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit" + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit" + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "chromium" + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "firefox" + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "chromium" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "firefox" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "webkit" + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "chromium" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "firefox" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "webkit" + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "chromium" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "firefox" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "webkit" + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "chromium" + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "firefox" + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "webkit" + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium" + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox" + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit" + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit" + } + ], + "reportSha256": "cad368f24b22c385f1325b795797ad74a464a036a5a8b9a1c46856769e16650d" + }, + "current": { + "stats": { + "startTime": "2026-09-11T11:30:32.017Z", + "duration": 26243.601, + "expected": 57, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "ab5d78e18bd7fe12b6bd7b09b8eaa2376d566d78720be58f808145247d6c47d0", + "cases": [ + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "chromium" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "firefox" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "webkit" + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "chromium" + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "firefox" + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "webkit" + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "webkit" + } + ], + "reportSha256": "db43485026c543d3fcee2763598dd476d242a9a341a1f3e613a130848a57507b" + }, + "repeat": { + "stats": { + "startTime": "2026-09-11T11:22:00.095Z", + "duration": 7039.883000000001, + "expected": 5, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "webkit": "26.6" + }, + "sourceBuildSha256": "0c5af1519243c0996f4286e3cb793a33e962f0c80f60623c36698e5df2539515", + "cases": [ + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit" + } + ], + "reportSha256": "084a934a07360991ffcf288f25bb1f7775f80ce932de1100f70e07e51c3953ea" + }, + "screenshots": { + "refactor/.cache/core23-setting-keyboard-chromium.png": "b635ba1c4bb829f1e8b2367f3b06cd6767c0d0cc3c51c498981df03ac1e054f5", + "refactor/.cache/core23-setting-keyboard-firefox.png": "1f1685c034cb4fcaba1a73cf437dacd26ad9b099af2ced5183536c759f13ac59", + "refactor/.cache/core23-setting-keyboard-webkit.png": "693d97dc5e16dd1a076bfcaa0662bb88ed0bcb6dd3531485563ce29256756f40" + } + }, + "probes": [ + { + "name": "core23-setting-first", + "stats": { + "startTime": "2026-09-11T11:05:36.152Z", + "duration": 10389.201000000001, + "expected": 3, + "skipped": 0, + "unexpected": 2, + "flaky": 0 + }, + "reportSha256": "46acfaa77721df91c2bfe15ce63ce71c69cdabf13ec2dd70d8f37e4b86e3ac7b", + "failures": [ + { + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-setting-item[data-name=\"quality\"]')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-setting-item[data-name=\"quality\"]') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-setting-item[data-name=\"quality\"]')\u001b[22m\n\u001b[2m 17 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 50 | })\n 51 | await page.keyboard.press('Enter')\n> 52 | await expect(row(page, 'quality')).toBeFocused()\n | ^\n 53 | await expect(button(page)).toHaveAttribute('aria-expanded', 'true')\n 54 | await expect(page.locator('.art-setting-panel.art-current')).toHaveAttribute('aria-label', 'Settings')\n 55 | await page.keyboard.press('ArrowRight')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-setting.spec.js:52:38" + ] + }, + { + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-setting-item[data-name=\"offset\"]').locator('input')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-setting-item[data-name=\"offset\"]').locator('input') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-setting-item[data-name=\"offset\"]').locator('input')\u001b[22m\n\u001b[2m 17 × locator resolved to \u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 101 | await page.keyboard.press('Tab')\n 102 | const range = row(page, 'offset').locator('input')\n> 103 | await expect(range).toBeFocused()\n | ^\n 104 | await expect(range).toHaveAttribute('aria-label', 'Offset')\n 105 | await page.keyboard.press('ArrowRight')\n 106 | await expect(range).toHaveValue('1')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-setting.spec.js:103:23" + ] + } + ] + }, + { + "name": "core23-setting-mode-before", + "stats": { + "startTime": "2026-09-11T11:08:56.247Z", + "duration": 10086.385, + "expected": 0, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "55e7081a04deb789c345fd57da88889849bbbf3a0805ff06748f3443c08b08a8", + "failures": [ + { + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-setting')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-control-setting') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-setting')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 57 | window.art.fullscreenWeb = true\n 58 | })\n> 59 | await expect(button(page)).toBeFocused()\n | ^\n 60 | await page.keyboard.press('Enter')\n 61 | await expect(row(page, 'quality')).toBeFocused()\n 62 | await expect(button(page)).toHaveAttribute('aria-expanded', 'true')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-setting.spec.js:59:30" + ] + } + ] + }, + { + "name": "core23-setting-before-name", + "stats": { + "startTime": "2026-09-11T11:10:17.860Z", + "duration": 10429.384999999998, + "expected": 4, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "b6f9d53a89634e1d99ac70fdb9286d801c6614d244f959c673fac67ba0acc757", + "failures": [ + { + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoHaveAttribute\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-setting-panel.art-current .art-setting-item-back')\nTimeout: 7000ms\n\u001b[32m- Expected - 1\u001b[39m\n\u001b[31m+ Received + 3\u001b[39m\n\n\u001b[32m- Back: Quality\u001b[39m\n\u001b[31m+ Back:\u001b[43m \u001b[49m\u001b[39m\n\u001b[31m+ \u001b[43m \u001b[49m\u001b[39m\n\u001b[31m+ Quality\u001b[39m\n\nCall log:\n\u001b[2m - Expect \"toHaveAttribute\" locator('.art-setting-panel.art-current .art-setting-item-back') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-setting-panel.art-current .art-setting-item-back')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"Back: \u001b[22m\n\u001b[2m \u001b[22m\n\u001b[2mQuality\"\u001b[22m\n\n\n 83 | await page.keyboard.press('Home')\n 84 | await expect(page.locator('.art-setting-panel.art-current .art-setting-item-back')).toBeFocused()\n> 85 | await expect(page.locator('.art-setting-panel.art-current .art-setting-item-back')).toHaveAttribute('aria-label', 'Back: Quality')\n | ^\n 86 | await page.keyboard.press('Space')\n 87 | await expect(row(page, 'quality')).toBeFocused()\n 88 | await page.locator('.player').screenshot({ path: testInfo.outputPath('setting-keyboard.png') })\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-setting.spec.js:85:87" + ] + } + ] + }, + { + "name": "core23-setting-browser-before-seek", + "stats": { + "startTime": "2026-09-11T11:13:47.492Z", + "duration": 106806.777, + "expected": 371, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "76e87c89a41f13ddbb16bf7667bb97bd59d6d8016d60da635f7c2afbb95a97da", + "failures": [ + { + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBeLessThan\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m\n\nExpected: < \u001b[32m0.1\u001b[39m\nReceived: \u001b[31m5.000204200000001\u001b[39m\n\nCall Log:\n- Timeout 7000ms exceeded while waiting on the predicate\n\n 56 | await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - window.art.duration))).toBeLessThan(0.1)\n 57 | await page.keyboard.press('PageDown')\n> 58 | await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - Math.max(0, window.art.duration - 5)))).toBeLessThan(0.1)\n | ^\n 59 | expect(await page.evaluate(() => window.sliderEvents.filter(event => event[0] === 'hotkey'))).toEqual([])\n 60 | await expect(slider).toBeFocused()\n 61 | await page.keyboard.press('Tab')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-slider.spec.js:58:121" + ] + } + ] + }, + { + "name": "core23-webkit-seek-probe", + "stats": { + "startTime": "2026-09-11T11:17:59.913Z", + "duration": 19387.268, + "expected": 1, + "skipped": 0, + "unexpected": 4, + "flaky": 0 + }, + "reportSha256": "fb4f46dcb6542957cc291de0714357352bbee0a32467d8a9ce210092f47c25b3", + "failures": [ + { + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBeLessThan\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m\n\nExpected: < \u001b[32m0.1\u001b[39m\nReceived: \u001b[31m5.0003882\u001b[39m\n\nCall Log:\n- Timeout 7000ms exceeded while waiting on the predicate\n\n 57 | await page.keyboard.press('PageDown')\n 58 | try {\n> 59 | await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - Math.max(0, window.art.duration - 5)))).toBeLessThan(0.1)\n | ^\n 60 | }\n 61 | finally {\n 62 | await test.info().attach('slider-after-pagedown', { contentType: 'application/json', body: JSON.stringify(await page.evaluate(() => ({\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-slider.spec.js:59:123" + ] + }, + { + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBeLessThan\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m\n\nExpected: < \u001b[32m0.1\u001b[39m\nReceived: \u001b[31m5.0001944\u001b[39m\n\nCall Log:\n- Timeout 7000ms exceeded while waiting on the predicate\n\n 57 | await page.keyboard.press('PageDown')\n 58 | try {\n> 59 | await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - Math.max(0, window.art.duration - 5)))).toBeLessThan(0.1)\n | ^\n 60 | }\n 61 | finally {\n 62 | await test.info().attach('slider-after-pagedown', { contentType: 'application/json', body: JSON.stringify(await page.evaluate(() => ({\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-slider.spec.js:59:123" + ] + }, + { + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBeCloseTo\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m, \u001b[22mprecision\u001b[2m)\u001b[22m\n\nExpected: \u001b[32m0\u001b[39m\nReceived: \u001b[31m2.0041198\u001b[39m\n\nExpected precision: 1\nExpected difference: < \u001b[32m0.05\u001b[39m\nReceived difference: \u001b[31m2.0041198\u001b[39m\n\nCall Log:\n- Timeout 7000ms exceeded while waiting on the predicate\n\n 52 | expect(await page.evaluate(() => window.art.volume)).toBe(0.7)\n 53 | await page.keyboard.press('Home')\n> 54 | await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeCloseTo(0, 1)\n | ^\n 55 | await page.keyboard.press('End')\n 56 | await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - window.art.duration))).toBeLessThan(0.1)\n 57 | await page.keyboard.press('PageDown')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-slider.spec.js:54:72" + ] + }, + { + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBeLessThan\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m\n\nExpected: < \u001b[32m0.1\u001b[39m\nReceived: \u001b[31m5.0002309\u001b[39m\n\nCall Log:\n- Timeout 7000ms exceeded while waiting on the predicate\n\n 57 | await page.keyboard.press('PageDown')\n 58 | try {\n> 59 | await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - Math.max(0, window.art.duration - 5)))).toBeLessThan(0.1)\n | ^\n 60 | }\n 61 | finally {\n 62 | await test.info().attach('slider-after-pagedown', { contentType: 'application/json', body: JSON.stringify(await page.evaluate(() => ({\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-slider.spec.js:59:123" + ] + } + ] + }, + { + "name": "core23-setting-browser-before-testfix", + "stats": { + "startTime": "2026-09-11T11:29:10.313Z", + "duration": 30742.044, + "expected": 56, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "a850e464374a317568fa8b706f276b5e5fd8020c33abd428f9fc4ba9ab248d13", + "failures": [ + { + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m0\u001b[39m\nReceived: \u001b[31m0.5\u001b[39m\n\n 136 | })\n 137 | await page.keyboard.press('ArrowRight')\n> 138 | expect(await page.evaluate(() => window.art.currentTime)).toBe(0)\n | ^\n 139 | expect(await page.evaluate(() => window.sliderEvents.filter(event => event[0] === 'seek'))).toEqual([])\n 140 | await page.locator('.art-icon-volumeClose').focus()\n 141 | await page.keyboard.press('Tab')\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-slider.spec.js:138:61" + ] + } + ] + } + ], + "provenance": [ + "Broad 477-case run started before strict-type fixes: source cleanup release now uses an inferred-undefined wrapper and the internal video host includes currentTime.", + "Current 57-case run verifies the final source with settings, sliders and source switching in all three engines. Do not merge the two build hashes into one full-current-matrix claim.", + "After CI, only browser-test changes filtered cancellation to the intended nonzero played update and corrected the fullscreen screenshot target. Focused ESLint was rerun.", + "An intermediate 56-pass/1-fail run exposed the test once(setBar) callback consuming unrelated native loaded/progress updates before the keyboard gesture; the callback now matches the intended played update." + ], + "remaining": [ + "CORE-23 remains doing and BASE-DOM-01 open; no completed-task commit.", + "Dynamic control removal/replacement focus, remaining mode exit, multi-instance/SSR/subtitle accessibility and complete core acceptance still need work.", + "Current browser checks use Vite source builds; fresh installed modern/legacy artifacts and the full current browser matrix remain task-final gates.", + "Physical devices, screen readers and release reviews remain gates. No push, tag, merge or npm publication." + ] +} diff --git a/refactor/baselines/keyboard-sliders-partial.json b/refactor/baselines/keyboard-sliders-partial.json new file mode 100644 index 000000000..130c51735 --- /dev/null +++ b/refactor/baselines/keyboard-sliders-partial.json @@ -0,0 +1,1128 @@ +{ + "task": "CORE-23", + "status": "partial-sliders", + "capturedAt": "2026-09-11T10:36:58.735Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "source": { + "packages/artplayer/src/accessibility/button.ts": "f6f67e19bbee2f1fa6a82828c451bcb86b5b1062575de411a0e72313a38c1c06", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/accessibility/slider.ts": "533d5e6d806c32a84a578b43ed50993d30b4a414b5a85a34bbc68c37c5673a44", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "a25464e14216b2be392fcb3fdda2439e6d6f98d1962f0acbba30e3bd53bcb2d4", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "42c192d23e347d74e0bb814697a4d59eac20afbec102a282d5aa15780cab5f72", + "packages/artplayer/src/contextmenu/index.ts": "4fd292a931b5bda9f16a1c2bedd50cd0d8c0b8fb6010ffc5faaad2c197d2d9e5", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/playbackRate.ts": "e177f4017ea9291794fb4023715c81bfc01f927324ab9bd0e32c741e4a3b0ca7", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "629c622864619e2515b2eacb1bdfcf523ccce7ce680c8fdf51812e8e50a0cc7e", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/keyboard.ts": "2e07680ce71ede06d6ba63cfc2c4a81a00dda5aab3daea1844552603a881f0ad", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector.ts": "fb055097eb38ea7cc488556ea52f3d185f437eb3de4dec7e09b601b01585d7c7", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "f82b0d645026121265cc8d780841a71ca5caad79ccec3765d7f03fc8aad3f17a", + "packages/artplayer/src/control/volume.ts": "45474d8d7f43d59263aa42e774eaaafeb45530ec24b81a5f589f6c906954568b", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "83a6e5c6d1923332973009b7ac1561f7a55fb72e5c60e5ebc88af1fa4b641d5e", + "packages/artplayer/src/display/mini.ts": "3ffae49b1407523da2dc5f2bc687018268f6c1d1d3c71911dd4aa96d1a66c1dc", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "6f78b34b903fb30653cc7169f43861f8be426d1f6e9669ef292e41a1606d685c", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "dd2c5cf65cfe35d6b5a87d01acb28f48119b27fe6e5f0c6a8b9bab3db1a1923f", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "f224dcd83c4ca5a1a862a91a418faa7d5e0ee9762408ee70f332aa44c8f59861", + "packages/artplayer/src/i18n/cs.ts": "6d39bb19b20080a5960b6fa0fdb0b9b031ed5a72a609a9c15b9624d3868399fb", + "packages/artplayer/src/i18n/es.ts": "b6fafd2309515439c033f61060d1d717d2becced6ef4b9c733162287f8218d8a", + "packages/artplayer/src/i18n/fa.ts": "27ffb3d154f30f592aa2df9193acc5bcdd11aed99d6fe4dd6117fe3f365df59a", + "packages/artplayer/src/i18n/fr.ts": "eef378e4ca959983fddd24f435441344026480c9c5878fd9d2f360e11ca37f4b", + "packages/artplayer/src/i18n/id.ts": "dfb6bb205a721014fe4ee1e27e78d9df91b8286f17bc336e7400258de64d60e3", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "552cebb3685f5eb98eff0d30d947a84e58460cba2f920f34d8be8b6ad44e7b0a", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "502595795c428f4b86bd3a8e86a87e54c77d0303c5cd86ea5d259f17ce400874", + "packages/artplayer/src/i18n/tr.ts": "9821f4652f56593c68110ddca34d9ed0616f1336267f17a33f01fdb5bd1e1e54", + "packages/artplayer/src/i18n/vi.ts": "4853b1c1fe1aca410c739a2017c3715fbcaaec2be47f3f0396f8ffb10be84987", + "packages/artplayer/src/i18n/zh-cn.ts": "81454382b97c0d2fa94128dd7e94c8089f13d16bc2dd9cacc58a88b7ddc9a130", + "packages/artplayer/src/i18n/zh-tw.ts": "22b7cdd27c117807f3990d3eab63cb09427bc79f1edf20356a2849cc45b5d450", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/poll.ts": "1d7a519dd1960c8cd5fb7a020d8d3dbcd2eb272b612d823f2167997751aaf663", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock.ts": "9a08cec3a92006be8a9d2dba8d850bc4f8f38d586a50de86d725d0d8929130fd", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f1e8a302077a8ccfa77c17ce344bdd6816943e77b5876c7f623314ff846742f7", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "853090bfffe579c5106124d64c8d2a646876448bcc7258740a96820d56508ad0", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a1bc04b99bda45cc1a2afcf2dd0925c88ccb55e169b971105277883ae2ccba0c", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "08298ce2c04b5c909b3cc9b1071d2e3e91a7096ba878165a55073e20c33321b0", + "packages/artplayer/src/setting/update.ts": "949c0001e9ae10c08ad9a9fce1c88603d98a9cb9b7ac5fa6620ee00a07933187", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "35d3fabf5415606a0bcf4c5f6c519d8b005a63ce1f1aeef67c75d0b37925266d", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "2da8fcde7d38ca29cd1e42cd57ab0b0d47fde2a2866bbd33223f5c8e459472b5", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "927fd6c6c5ab440a2b25ecc43211ab89106c739385385b62de3880ed45dd7601", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "589d05e12a62e04fe848b36ba748433d23f0b909a04e861b1d6737f2799be183", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "295012ba379a7e957a24476616a0c3623d6a06e82ebbdaa45b916dd6412d7f4f", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "6e99bbe0dbcb40667ef99789b65812dc9c94ce8a1071c00d2edec5eba041c434", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "c8ff22ef3774cf7d97713638cb562f1bfc11aa113df5c625a2c20527ffc450ad", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "declarations": { + "docs/assets/ts/artplayer.d.ts": "352ebb2c372e3a344a3bfa2264729d26e59ffb5019f36c51978e73c2c7696e59", + "packages/artplayer/public/i18n.ts": "1b3354eee715b596022ac3bf83c8304f2e05ec296e966497cc8405b1886556f4", + "packages/artplayer/types/i18n.d.ts": "adfe931b8e707669e6d7ae6b2c42fb3b3ac40c7316cf5f846e0817af160e6b20" + }, + "tooling": { + "package.json": "315746ada69ccb62b8b8c10016b3e467667db9e39518b32dc8036cbade662ea4", + "test/accessibility-slider.test.js": "1d392af761f8d006b4341d621cd87636eb161f8cf7151d2c37cff8354a1fafbf", + "test/browser/accessibility-slider.spec.js": "1a75012aae760cd1e3a2344786b3d7a5c80099f577e7e76235e7bc908fcbf9e3", + "test/browser/accessibility.spec.js": "f10bdefdaac2359d1af5d2099cb8e1770bd7ca486362143f663b5c54459d6cab", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c", + "test/browser/progress-quality.spec.js": "824596e3f0f1a7d8304ca7fed38de4f00b2f967eb87fd48346ad714fbb2e280f", + "test/progress.test.js": "3f6472aec1b2534d894d05477b19d77404c064e3d448531a005786f75a947b2f" + }, + "ci": { + "passed": 463, + "productionTypeScript": 234, + "logSha256": "dffb9c886414bd6ea46182dc2bf7a0ada7ceb1e0be646dc95e517debbbc15429" + }, + "browser": { + "stats": { + "startTime": "2026-09-11T10:34:27.781Z", + "duration": 52538.817, + "expected": 123, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "sourceBuildSha256": "b354b729134d8d4ccf1a250210ce78ea467568b34119ab0605139e2b5acc516d", + "cases": [ + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit", + "passed": true + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "passed": true + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "passed": true + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "passed": true + } + ], + "reportSha256": "468a73650514dfda16e50625581a3aaf38ace0004622e31ddddf8567a8487a2b" + }, + "probes": [ + { + "name": "core23-sliders-browser-first", + "stats": { + "startTime": "2026-09-11T10:30:22.959Z", + "duration": 10697.682999999999, + "expected": 9, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "163fc23eabe09388acd4752b51cddc409b10552f19a9688d6bd72f2b36ab575c", + "failures": [ + { + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-volume-slider')\nExpected: focused\nReceived: inactive\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toBeFocused\" locator('.art-volume-slider') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-volume-slider')\u001b[22m\n\u001b[2m 18 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 124 | await page.locator('.art-icon-volumeClose').focus()\n 125 | await page.keyboard.press('Tab')\n> 126 | await expect(page.locator('.art-volume-slider')).toBeFocused()\n | ^\n 127 | await page.evaluate(() => {\n 128 | window.savedVideo = window.art.video\n 129 | window.art.once('muted', () => window.art.destroy(false))\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-slider.spec.js:126:52" + ] + } + ] + }, + { + "name": "core23-sliders-browser-before-timing", + "stats": { + "startTime": "2026-09-11T10:32:17.492Z", + "duration": 58308.914000000004, + "expected": 122, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "174d2aedb026b32b63e56140c6fdefe76022144cafcb05c7bc1bbbb2c1006113", + "failures": [ + { + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "errors": [ + "Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoHaveAttribute\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nLocator: locator('.art-control-progress')\nExpected: \u001b[32m\"1\"\u001b[39m\nReceived: \u001b[31m\"1\u001b[7m.0031152\u001b[27m\"\u001b[39m\nTimeout: 7000ms\n\nCall log:\n\u001b[2m - Expect \"toHaveAttribute\" locator('.art-control-progress') with timeout 7000ms\u001b[22m\n\u001b[2m - waiting for locator('.art-control-progress')\u001b[22m\n\u001b[2m 17 × locator resolved to
…
\u001b[22m\n\u001b[2m - unexpected value \"1.0031152\"\u001b[22m\n\n\n 36 | window.art.currentTime = 1\n 37 | })\n> 38 | await expect(slider).toHaveAttribute('aria-valuenow', '1')\n | ^\n 39 | await page.evaluate(() => {\n 40 | window.sliderEvents.length = 0\n 41 | })\n at D:\\github\\ArtPlayer\\test\\browser\\accessibility-slider.spec.js:38:24" + ] + } + ] + } + ], + "recoveredEditorDrift": { + "logSha256": "74dfd58f98f6cda82e976a13189d2a3b271f5a705c440c93f188432d07648d82", + "resolution": "yarn build:ts regenerated the optional Progress key; final CI verifies reproducibility." + }, + "remaining": [ + "CORE-23 remains doing and BASE-DOM-01 remains open; no completed-task commit.", + "Control selectors, settings tree and focus restoration, mode exit, dynamic focus removal, multi-instance/SSR and subtitle accessibility still require implementation/audit.", + "The browser suite uses a source build, not freshly packed modern/legacy artifacts or the full browser matrix.", + "Physical devices and screen-reader evidence remain release gates; no npm publication, push, tag or merge." + ] +} diff --git a/refactor/baselines/keyboard-validation.json b/refactor/baselines/keyboard-validation.json new file mode 100644 index 000000000..955d68a89 --- /dev/null +++ b/refactor/baselines/keyboard-validation.json @@ -0,0 +1,27586 @@ +{ + "task": "CORE-23", + "status": "validated", + "capturedAt": "2026-09-11T13:03:44.622Z", + "parentCommit": "faaa3e8c2d84a9b7864e81e06cbe5bb66c517bd6", + "node": "v24.21.0", + "yarn": "1.22.22", + "compilers": { + "current": "5.9.3", + "legacy": "4.3.5", + "preciseMinimum": "5.1.6" + }, + "source": { + "packages/artplayer/public/artplayer.cts": "0e91e907d021db02a68004603e6190505fdc0806d873ebb6af171aa089a81da7", + "packages/artplayer/public/artplayer.mts": "f6292596a9ccb1d43a6d6a12c35f859b1889ad15924c5ae0f9f280941aade313", + "packages/artplayer/public/artplayer.ts": "26a42ac66811e70f68a8ebe62cbf304eb1993451b3e658961be98e7106162527", + "packages/artplayer/public/component.ts": "aa1c43be67322781b4b355b143bc69d9f29d22e578e4974d6a13e957a7c0334f", + "packages/artplayer/public/config.ts": "c4fd8681bf32b10c743e3e561c532520c8f32e43fd765524850b15e55cb91c72", + "packages/artplayer/public/cssVar.ts": "e027d82fb4f01c9ce7559cf679b2d5ee1962d3f7e5b4dd64ca21f472b933efb6", + "packages/artplayer/public/emitter.ts": "9c62551cdcc6dd3966bed8a7a85dd477435db977c91a294d2ac8f162f9592537", + "packages/artplayer/public/events.ts": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "packages/artplayer/public/i18n.ts": "34b0c684668044f7600c80b9d3979f8fb730138007b7cb4e7034326b340156fb", + "packages/artplayer/public/icons.ts": "0d8e8e52e52130dd4a29bab551dd7a2a954797e42e92a6e068c85d583e23e6a4", + "packages/artplayer/public/language.cts": "2248040d86a8e34626755c4ecf53ea0174706c653073cf0e15884a030d173120", + "packages/artplayer/public/language.mts": "c391e863012c77769e661afbf8fa949e9373aa88d17f58cbba7f5696edb8077f", + "packages/artplayer/public/legacy/language.ts": "c452ffd764ff9b29b819b3475c42395d2ea7a33560d8c186ef5df3844b9524c3", + "packages/artplayer/public/option.ts": "850e5264219b8b438c80694402225b690b131786677a5da0d22739ec2352d263", + "packages/artplayer/public/playback.ts": "1ceaed3aa1cef511fe8b20f4874647f6065c723ad805b742a0a9247e16bb1bb5", + "packages/artplayer/public/player.ts": "f1e50257df2ea592d0a0e1f36078dda77eaf2cf3b3d795307501396562d99f28", + "packages/artplayer/public/plugin.ts": "2a57e148fda00ee687da5036b890b0f611cb94bb403a1ed52602179060259d35", + "packages/artplayer/public/quality.ts": "7ed6ed78cea52991b2f6ddd2bd3b7bd8c5146fdfff7486fe8b814c3e632f1567", + "packages/artplayer/public/runtime.cts": "52cfff1daeb6841a90212c8fa8d46ca46d6650bb7ed1b59b62115d854b8ad652", + "packages/artplayer/public/runtime.mts": "1b09bc0ee0f0ee2f788689eaff441bdeda1fab0ce783e71b61b9792d81072b03", + "packages/artplayer/public/runtime.ts": "ec4b1d56993eb482a77eb0f94b701047549d009e6ba6433f27e7d464fef30c2b", + "packages/artplayer/public/runtime/component.ts": "840213299c942fe058eb5436977ceec066b9dccda24c55ae9f464b399c979e39", + "packages/artplayer/public/runtime/construction.ts": "24cc5cda1f614314db382271a9b0d5583b781894cfdf6c548700b1b5270467ee", + "packages/artplayer/public/runtime/events.ts": "52848f57d35eb1037cf74c8877521edf99a015bcd77f30ef6bbcba1807a99bfe", + "packages/artplayer/public/runtime/media.ts": "8828f80953aec3e95328cefe691661e8897cb27cb309483cf806ec45a8549ae3", + "packages/artplayer/public/runtime/option.ts": "bb672e49ffe74a6fc78543217f6de80d7d738890146df0857c709d4dc283e4ce", + "packages/artplayer/public/runtime/player.ts": "a4a24794e26cfb9e4310bf0f459a7a407e85bf81b4f3a4feb6294331af8036fb", + "packages/artplayer/public/runtime/plugin.ts": "9ad482f2a77914a91450419680b8af6b314b926f0831c2f7f6d7c466690f95c9", + "packages/artplayer/public/runtime/services.ts": "8e4648d8c61bff47343f9e1c2b995af69fc00947264b826109ceadcbaf553254", + "packages/artplayer/public/runtime/setting.ts": "c48d20957b57f79f985ef76a2950cc8a5cfa25dafa8ec5939e562661778e6218", + "packages/artplayer/public/runtime/subtitle.ts": "13241c4f9a87517aa2cf7b3e0bb8cedaa12fa0b4d3f8934285797583b752557e", + "packages/artplayer/public/runtime/template.ts": "da9975513a1938e7f386f4f65f718f0fc595164bfeac8f0cd99a3e97a54919a1", + "packages/artplayer/public/runtime/utils.ts": "cab9916f5224a3b047812b9f759cc9cc62105662599744067a6955020ab36916", + "packages/artplayer/public/setting.ts": "d12a75b656fff70cbb30be4bffec46d9c4273636e8722bce971a4d2b188712a1", + "packages/artplayer/public/subtitle.ts": "d25b470e47d6a9bd696d9c1ad8adb58e56a208f05695186d513bc8c43c2e8acf", + "packages/artplayer/public/template.ts": "68aed9e97d006d6be4fabb8504ca84dafab770b0925f4d6e7319e67c82f21b0d", + "packages/artplayer/public/utils.ts": "494ec447ab467a07ddd7a2c2abf778b3fce69fd28a09aaa8ced9759f8de2e3f6", + "packages/artplayer/src/accessibility/button.ts": "e5afa7aade56116082f54678c44961157950fa550d66e21a4e1ff9bb5369a6f8", + "packages/artplayer/src/accessibility/focus.ts": "2fa16941ac3632cb1e4b466e9a7e29700ef97b7eb2facd4330c59ec0a9320594", + "packages/artplayer/src/accessibility/keyboard.ts": "2d82122732f84f39e59c6852ca081614caa6430a82b32c4749e297826c77eb12", + "packages/artplayer/src/accessibility/moved-focus.ts": "c3d2a7d496381b2a86819b82fbd26cc940a1204fdf19408ccc8db267741d96c9", + "packages/artplayer/src/accessibility/overlay-focus.ts": "93fa088daaa3afed88f645507828a10cb63292937c49b16f6c2a0ea895897878", + "packages/artplayer/src/accessibility/player-focus.ts": "e8fd5222cbfc38cd4938324c83d9f5cef3d01a439464e1570d63a5131c84f20a", + "packages/artplayer/src/accessibility/slider.ts": "533d5e6d806c32a84a578b43ed50993d30b4a414b5a85a34bbc68c37c5673a44", + "packages/artplayer/src/accessibility/suspend-focus.ts": "d95c6097236be66e252165287435cca01b50553d64259add6b011721e4bbc644", + "packages/artplayer/src/bootstrap/browser.ts": "8d401627e8ea1c87fb44204227b04177a70cc7a0f79f95fb5dc73fe828e46a8c", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/focus.ts": "f4aff802711f6146c80e8c6bd90bc2cb406ccbdb581aef41f436ff5c03871ad3", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.ts": "a56b4d3d6942cfa3e2b47f909fc5ad87e6e3202fd61b29c7afd7649049e31d05", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "18ab60c9acee1e0cecd76c0b6cf750763eed7cfbede4220328b5200154c5c478", + "packages/artplayer/src/contextmenu/choices.ts": "6bb880b27afc9457442c3973992da6dc8da48fc61d6b66b3b5a3bb4fc4651dc8", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "a7a4ac375da45dc7b6c996d4534098838646a078abfc4438f688e91e14ef0b38", + "packages/artplayer/src/contextmenu/index.ts": "7532165d162fa463f1fe3c538d6bda0f579b5907b05137382efeb0018719b011", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/keyboard.ts": "eaa1af6b1abf8947d957208a0535f1b34f6c88e95394efd56cae905ccdea564c", + "packages/artplayer/src/contextmenu/playbackRate.ts": "7e06bb6fab3acdd71fb3ed63f77083172af517b49c1ecaefa3ee6a9068bdfe54", + "packages/artplayer/src/contextmenu/position.ts": "851ed1a884a13fbe430be77e7f72ae46d8a719175647e058644834aabd27ac58", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "539bcc3671c7fe428ab95f9fea8a4943444066bcb742c7cf71591ba347642547", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "7f8a9e8915abf9cbb9dda05b5c68523a47cc0ccf9ef5e0d9b82bc5c362fe346d", + "packages/artplayer/src/control/fullscreenWeb.ts": "9cb30987a3d2cbb334a80d3f2c41f39fd339bf37a9524c7ed0145cf5c98f1859", + "packages/artplayer/src/control/index.ts": "0d8e5a281f2eeba06c4cc4ac5a042847df53db1a19fdf140efea17d6ab2c0b78", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "b829a7c83c5efa6751c2e434345e077339c9f5bc5022af9973f181ca8ce7f7ce", + "packages/artplayer/src/control/playAndPause.ts": "20ed88bcc7ac7622e02a7c4e6be518582c05f0d7c571a97a54b851d79dcf13c5", + "packages/artplayer/src/control/progress.ts": "629c622864619e2515b2eacb1bdfcf523ccce7ce680c8fdf51812e8e50a0cc7e", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/keyboard.ts": "03d1d47e6641ea08f765d731f10a6aad35f7c3edc16aa97df822c5f9a7f75eb0", + "packages/artplayer/src/control/progress/position.ts": "a3794ab5ac5dafa5fd61e56acb12c94998bd4b9065dbf0fa4739c6bba1094aa1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "11a1e3da919e476e7882abc3f74aaa809c3e9fc1de4346ec808731f78b6f27e2", + "packages/artplayer/src/control/selector-keyboard.ts": "6a749f48b23cda62148298e648bb380a6067cc18c7be4258b9ec85c382a56165", + "packages/artplayer/src/control/selector.ts": "a6f0c564c674530da9a0e4ed8762c6dfb81fa89373d64313e1020550731441f6", + "packages/artplayer/src/control/setting.ts": "10ee1118858c41f2e97a6df70d6d5dc978757d0e5d79ec36c11e743e6df86726", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "454846310d4fc3a8576ba030c2e8428bb795cde7b89308d29943bb4d4bc2aaa4", + "packages/artplayer/src/control/volume.ts": "45474d8d7f43d59263aa42e774eaaafeb45530ec24b81a5f589f6c906954568b", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-focus.ts": "1f717619e183b1cfab668bd2e41c8e9ba02210c94cdb58034ec97aa41e71aa34", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "bbe69e4419ffc0f6c744cb730a51778f23c311a0fac157223bcf8d8bf0f3edc7", + "packages/artplayer/src/display/mini.ts": "a6fed598428bbf8d52931f21bb68b7560a3643d2576f7e7bfbae98b2f7cdd1e5", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "0d68d2bc99d04db1e2fdf16b74e406e31f8b7e03fd9b6ea271773ed263ffa890", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "e88c868fd370fcc9dc612489992d446a8d0558bd87c26c5c05fdd73d8a3d1b02", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "bc091e6dcfb28784dd40ea619ce1fb9061b9e85dcc5bf2b6a303679eee5c727d", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/dom/event-path.ts": "e952ea847a2e844a79c5c1b83035e03917e0294b80b1eb8af3b3bec0d2f7d333", + "packages/artplayer/src/dom/measure.ts": "84a599351d26a790c5a8f6e7d271486a0a68d5b58457d8ce754d540b54902b96", + "packages/artplayer/src/dom/presentation.ts": "500bded394579dd8194778f73cc44d0724f0a59cb5400957491928534ed091c6", + "packages/artplayer/src/dom/styles.ts": "734e0a4e04d666417a18ac09ed6271ee7630c399d52d7f510a1c19fd6e7b3493", + "packages/artplayer/src/dom/tree.ts": "3bc517ab9fa5317a1445156d53afb27182685eb3b4c0ac2ff41bbde55c9eecb6", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/core-types.ts": "a607a3b2eea1b031f23ec0f620f1f4cd68799c4a77138a1443ecb196b00d1662", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "da97591723f8b94a34702559b7ee67a35f172aa696d37dfbecd472581ad3de35", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "0fd98e94397064f32cae4c004d9932c006d2db69a7d6d9374ff174d74ff93cd4", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "897d8935384da16c3c4e96480777fe7fc022f6e3c0d87f62f79ae5f3c98e228c", + "packages/artplayer/src/i18n/cs.ts": "cc154ee50d258495d04dd2d49e89e9c0166e8b368969c443ec80cb5e48cf357c", + "packages/artplayer/src/i18n/es.ts": "0ed0283cb78847d6d1674be8c8ffa45feab88beaa8dbd11954b793c7b1657c75", + "packages/artplayer/src/i18n/fa.ts": "a72e83717f2e3e8f19f1de82516aef4a54ea70563223637bcbb25d21e9eac084", + "packages/artplayer/src/i18n/fr.ts": "a7366c75530e87f069216e20a6f09da42f7e77fdce862c02b32acf311068124b", + "packages/artplayer/src/i18n/id.ts": "146bf4c4e5bb39d8e1eb1a6fe3c639eb3128c55789de20511201f8ec02c56c0e", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "420f3b620d5c7ccdeba7857872be6176239fdf5da30b9cc72341e85dc95c2c8d", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "9a9f61e6a66b3cd884c609250bf765dcdbc850dae3270d8a1600a5c2542436d3", + "packages/artplayer/src/i18n/tr.ts": "631c262a5e6cd00fada5bf2e146007d845816e47edb7643ec792250a403e4ec6", + "packages/artplayer/src/i18n/vi.ts": "e6f3f8e53599e27755e162c76c3b049457aae7089eca73ee531986e67f517f6f", + "packages/artplayer/src/i18n/zh-cn.ts": "51eb75562ae1ae4e248e1db85c90bcbc69b388a177ada6cbf8c3196a2c343ac6", + "packages/artplayer/src/i18n/zh-tw.ts": "6b098739e27ad531172d0f13e53849be30e9936365ce9613a7d938d9f01cce53", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "7152126328f6e485ee92b6d924c34776518b4a3925b2887867b516f7523b15cc", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.ts": "20cfe3738b3ce7e11b69721a5f0bdad9db77807417d8e421397a40dfade4c047", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/info/keyboard.ts": "13a6f617514388b4d14e0bf752780937f2baf545edb216b8259f56a198112c83", + "packages/artplayer/src/info/poll.ts": "d26ff67d9eadf1e032445371dde6f15293a7fc0b2ae6b87c3815e4b4e1ed5dda", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "5ed25db69e0d9579a2fc0ab6faadf00fa073ad73a1ea5aa48096b4430c71141a", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "c7232470d725f3700481ab98bf9203403a67f1ab82e72394baa9c3ad6f3c9a4b", + "packages/artplayer/src/input/keyboard-focus.ts": "270c9dba40c0eb6d9fb36118b53e7f1d42a301ba4514917849523b6a05ed9e11", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "63e679498f8f42f6842f63e910c38717ac3438d58df3a75ef5b77c009b7931d4", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "3168f7db4271bae7a242e80798546b755ac15443e15dd9ebb7675f5a259299d8", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "02bd29ad8b158fa04ce5c1524e397260ef24b94c2cf1f053e7bd02b23e5d29dd", + "packages/artplayer/src/media/hosts.ts": "498d1cde31bf9ee12af1f13523eb0a4553adb285264529378abba5b629829e9a", + "packages/artplayer/src/media/playback.ts": "b0364027e1ea26e44e435a938e93c022836885c2622cda6bc3a7ca791d3c2964", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "4faa700323a8fdfd91a59491a5f57da2dee9bd1f2de0d900ed16e9809a208c94", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/runtime.ts": "d1bcc7682da05a74d7af173304e47f71ba9eb59e5351436040e9dbdef5c58fa8", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.ts": "bfa30e1dcd7cbaef97e977344e8a35524fad6bd23089cd8e45945e3b32b4bf04", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.ts": "d82150611a69423ed46bf673f44c3e0f61e80425026effd486a6951b6c0dd90c", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.ts": "0d023f28b7a8b4c1a5e2c4dd5672ef4294c86bce0013babd9d52efa32a443b2a", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.ts": "359943c88dc99863e510fc0d51f8e8ee2397217e68045f755d4e9538579bdaec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.ts": "7c1c47679ee6201d0e0d203fc7b449a09309e7b24a0a1099ad259a70fc1b1a35", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/posterMix.ts": "d569dc24e8e64efe398bd76942bfaf563ffbf64d2a7387ea2e1cb1cf511183d4", + "packages/artplayer/src/player/properties.ts": "76806d6273545ff556cf9c6d341b59b9041455a8ecbe1fd40510e841c0d5710b", + "packages/artplayer/src/player/qualityMix.ts": "980ff584c8a5793f5ec9f049f144df31d184d7c9acef49fbe9d504b7657a96bb", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "1754bbce09f713204c120cd4657b52c06eb09eb1fe3244f84474e5967cd68e50", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.ts": "5bf11bcf8b77cd5d5f2970bc3edcee315c693c1be3d567770d5107a5951cb48f", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.ts": "c2a234a9c09f0269a4bd0659087635995945075ac70a5cf2478c8a135fc1b2fe", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "58c6dcaf540296ee6f6bdeeda38ee7302aca2b06ddb152b716c0c2bf9c6c96b4", + "packages/artplayer/src/plugins/auto-playback/records.ts": "133a4ba2fd2d3df724d96eb203d05cffb0b82ecb8de72403974f7979bd37ce01", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "4631c9775732982dfdc87e16b1bd6b41a350be36fb27e0a9132c11a85b0c016d", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "4c97f354769bbcb338263f321876a90745a87a9af2d267e216bd3d9d007f268a", + "packages/artplayer/src/plugins/lock-keyboard.ts": "d59ac2fc9d0daf48c7946e0b49698a74e01f5f55e903c1b090fbda5516cbd16f", + "packages/artplayer/src/plugins/lock.ts": "8f5fe4469787b7b2a0a302d0fbd925f8eb6d1b261cae6e17367e4d97666a096c", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f6319af15ebe3600a466123dd9d343b86a8d6ed201693ac7ac86dc1d674d477f", + "packages/artplayer/src/setting/keyboard-focus.ts": "d66b7e2ae3693da3ee500d1fc57346310066c3a1cb34d7433ebadc70090417ca", + "packages/artplayer/src/setting/keyboard-item.ts": "d94bfc0266486615ddb79b9eee3886f48891ebb2e5f465652ef98f142ada89d2", + "packages/artplayer/src/setting/keyboard.ts": "99db705c0cc87d5d7fb5dffbee9f2a88b7342b6661fd6d00addd17a815792bdc", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "ed73745f2c7e2d76bbe8ce7202336e5f4de217dc8f0806b769127cb25316faba", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a642e630924eaf4ad91705fad1fa6e6dc946b32970d809a23da274399fce20ef", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "21a07d75a28bbbe20b3e107b6f1a09cb6f8ef2773ea10a4bd7caa88956e9b99c", + "packages/artplayer/src/setting/update.ts": "79326cb55c52243a7aa8df347a3b081dcd84eb7932fc6162061cc0d9f7078add", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "da98a47e8419b33069191e51fc94cc9652302ee4f3eff8ccc7a6dbd4c4c0e2bc", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "e5fa3a9cd6b84dffbbb02f61aad966d6046204d857de3e4564c795f02a0259ff", + "packages/artplayer/src/storage.ts": "9c0a0f3d8ac18261db6e49b2ea14322d1d53bfec3531c7337b85005e708fef30", + "packages/artplayer/src/style/accessibility.less": "eb9cfe282c64a059d2e102280750bcd33ac33726fa09042eb9875f534335efef", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "7fece0bc5b5a106d051eb80152d5e4558f2e73953c4c33175aa901b9695be61b", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "8be782a3054154ab908b1cce650b6131330cf0f0e936b749accb4b2dfe605a27", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "ea345094ea5708dd3a3c290f357dbb301b38af35464d213c47e3ec6c60eaadca", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "44585c6b0179e34d21eeefce6d3494faacc0e9d108079426876e8847fd441513", + "packages/artplayer/src/style/setting.less": "5618eb443ab6368bc4a18e9a379ce6552629555cdca6074e753aa6fd7baf9bf9", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "6e99bbe0dbcb40667ef99789b65812dc9c94ce8a1071c00d2edec5eba041c434", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "615e389b4bb36196a69a059eb04cf7e519cdac13d2da15e4374fede2f3b6631b", + "packages/artplayer/src/template.ts": "0ea9155b9292d4c528a464d3c97996ee5a1c9c4aabc2959a744989085db2251b", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "2bf906b4a209e17dae4d79225e758e2e53772e93f19f188d0131051ea2a0143a", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.ts": "1fd2a5b17ee3245712eda961d3c0a15caf3c428010112e48231890176ce1e5e2", + "packages/artplayer/src/utils/component.ts": "c3fa96467e8b315d974a42a19591aa4a4a7514853db796135b2acbcdcb160ea3", + "packages/artplayer/src/utils/dom.ts": "72f3539dabf296df37ab4cc7ade0c8ac9480f399987101589450c787e7d6719b", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe", + "packages/artplayer/types/COMPATIBILITY.md": "a7da9e102a116104b513df4f7451247b7759bc502d3375f30bd5b14a541826e0", + "packages/artplayer/types/README.md": "1bd9868e773610e6312fd48a1c5aa20772d29df0af40c3db66e75b7ab4a1aee0", + "packages/artplayer/types/artplayer.d.cts": "3685065e4263abcfd9d953176e461d5b3eb990b0363b54689a7f55deba770fef", + "packages/artplayer/types/artplayer.d.mts": "b664fec51ee5c5381f2ceab25d99d52aee56feab04a2ee7b4ea5b2145ea5fa0e", + "packages/artplayer/types/artplayer.d.ts": "5d0162adf7ac6d0f2bb9b5cfe361f28657c4d9c540cadbf36eba3cc954ce50f8", + "packages/artplayer/types/component.d.ts": "ae5bc1ddeaa1ee1ebbc62573e32423993727079205c64751a5a314170e588a32", + "packages/artplayer/types/config.d.ts": "36f9a84cd436f17701a0d11d3417fc1fe0414e0c52c80083b94a85dfc329e37e", + "packages/artplayer/types/cssVar.d.ts": "93217860fff2ebf750f606d95ddd22220a58837119e63bdf2f5f78fd7488458b", + "packages/artplayer/types/emitter.d.ts": "7e1f9a2a8ce65feb95734f1ed52d1334e57aa388bbef2a43d8bc53a9b6f6623c", + "packages/artplayer/types/events.d.ts": "f83624c9268a284477e8bd793fe3562a2363b72f2a44d5c64fe8c6a6cede8830", + "packages/artplayer/types/i18n.d.ts": "f4f2f05bdfda73c74fef34767cb18ee8e11b743120b1c4598e9714d7846018e5", + "packages/artplayer/types/icons.d.ts": "326a67ba7bdcf52862c5b2a269e540140aff98d05c7b96196485a77f84fe5960", + "packages/artplayer/types/language.d.cts": "f7928e108cf7b7814c2d75cb0a525333e95873fca6cd6d89a740450656b9c1cd", + "packages/artplayer/types/language.d.mts": "6619a26d604b7cccbe2f596243d87ae37cfaae33b8b52874ec071d9787446f9e", + "packages/artplayer/types/legacy/language.d.ts": "c7abda4d506fd933c350e9030290bf9e64347a921d683a66115da1995ebe0a81", + "packages/artplayer/types/option.d.ts": "ccf2c8ddc537dc65c9682d39f044726e23bff18f476b622512d7e6a4b949b5f6", + "packages/artplayer/types/playback.d.ts": "58705c273df6e76a77a6575e769a9ec6c013785c25080f2551aa22415788d870", + "packages/artplayer/types/player.d.ts": "92b00211b70ac71336e495899df972a0519dd138111846044fe4e0f967966177", + "packages/artplayer/types/plugin.d.ts": "fc3594a41c51d8248713e33c486fb1f6a518ac5c7ce31be6988a6cd8d052c5f3", + "packages/artplayer/types/quality.d.ts": "1ac1a48b4f74ff9ba1ce60443e1463d50d1c6a2e5d87d63dc7d2a8eb7f4c2c34", + "packages/artplayer/types/runtime.d.cts": "7ee988dfea9a0ac71a34a656f96f7b74e78aa92547cfdfab7ff7e1139a77d4a3", + "packages/artplayer/types/runtime.d.mts": "dcb85f59a8b7714918ced0c1d18c2bb24e8b80b56d8c594e019dcbdb5ad88b08", + "packages/artplayer/types/runtime.d.ts": "9c6ccd39a1be293f17ae46dae8ea077053e12635ee79d73a5e3b3a559230fcff", + "packages/artplayer/types/runtime/component.d.ts": "1b4c0cee44568649e80140fe778febfcae88af0ac85515f1cbeff78ab0c6d14f", + "packages/artplayer/types/runtime/construction.d.ts": "7a87bedf6f7ffff0c46078aa5f1551e0077d35574e286516121f5f935e2d9ce4", + "packages/artplayer/types/runtime/events.d.ts": "a1e2f9d387475453eaf95c2a5ee79e228636c0bb859bda3fcc46da46574a0c31", + "packages/artplayer/types/runtime/media.d.ts": "8fc89401be7fe25542c169d07dd5675f10916ed20be8493e19695966cf3864a8", + "packages/artplayer/types/runtime/option.d.ts": "6e334e1a76fdcc40b4665c02523bd31c3994d96078fadeb40e23422aa54c1a1d", + "packages/artplayer/types/runtime/player.d.ts": "8ac6383502e4872e83659838844856903031a81a0adc8e8535feb78453aa042c", + "packages/artplayer/types/runtime/plugin.d.ts": "8528f2b17843149f42f9cc16d6fd70baa238c9dc2c329b67d2c38096799c69bd", + "packages/artplayer/types/runtime/services.d.ts": "604c9f8e4b6c0da818f96576bf9f4b0e96085a9003927b2f7ba30027b1ba237e", + "packages/artplayer/types/runtime/setting.d.ts": "349c1fcb205ad312916bd3ee55e6bf241ea8a569fb2ab6c80822e69fc518f7d7", + "packages/artplayer/types/runtime/subtitle.d.ts": "269ff84678d327b3a9dc2f5bc6cc0d731d1e081b85422e474621d5d792efb153", + "packages/artplayer/types/runtime/template.d.ts": "7a62f968a38b4bf9109a4439557c02074eb1d62ba1f6e21a8eb194e91f0badfe", + "packages/artplayer/types/runtime/utils.d.ts": "6bf731705d86853e066dbaf3b8d4003b6548423fe615b7412b722bd0d3a6e48b", + "packages/artplayer/types/setting.d.ts": "08305a75dff96f06490430e099338b463df471b550c1d0dac3abc8995b39eb09", + "packages/artplayer/types/subtitle.d.ts": "b18314e2d64efdb6045830b6e12f615ae2ed585416130e562329ad3ea337f6ce", + "packages/artplayer/types/template.d.ts": "4792bc0c2cbcb7966e4375118bd34b326166e0831862e94ace4cf6b1bbe6a8c8", + "packages/artplayer/types/utils.d.ts": "fca0d3d814df94a25f9eb067c86fa0cf272e2791bac793b91229d57680797712" + }, + "tests": { + "test/accessibility-button.test.js": "8def35ef049277d08fcc8389555a53b44273965e143ef91aac85b97f1c32c443", + "test/accessibility-focus.test.js": "1210380f832b0dc04b25031549581adf5b809d41a217aa562f53ece337318a11", + "test/accessibility-slider.test.js": "80238f1faa8f3fbe440e78613260b5cdf1e0dbd7b65738213749c5e8c90ddcee", + "test/browser/accessibility-contextmenu.spec.js": "f7d4be7e317abe7790bf7134479838b0d775974d33bd5bda97319708a6876b27", + "test/browser/accessibility-controls.spec.js": "d07d9919b9e9d960116770f82ebb61d165bd4b9fbc343a4e821d9cf9313dccef", + "test/browser/accessibility-info.spec.js": "348268395523d4fb5c2d9b6a2486cfb0d1e1b8ef84d13e97ad9db22f5e3ed173", + "test/browser/accessibility-integration.spec.js": "b79613a0352085015ea058c35486fbd845155593fd11e3dfca9e7345279a14eb", + "test/browser/accessibility-lock.spec.js": "2c208fa3deda0f10769a95c697cb7618225897ede408d857d107706acae5e7f4", + "test/browser/accessibility-mini.spec.js": "a0d667265145ff24e37624775ae388f184ad425c4844c47ce8c692de31123a32", + "test/browser/accessibility-selector.spec.js": "aae91d2449e2257bfd19999505cf0bb5c631bd49b0dbf597ea1ac48e2f2a25d1", + "test/browser/accessibility-setting.spec.js": "dab5232dc5a964d51d46ec4779b7c675acae8aa210424f86128d694ecc20d85f", + "test/browser/accessibility-slider.spec.js": "b88aa23fc1b76e3a902150a8a9d4a801531f397b0a27120b4741baf67f82bc47", + "test/browser/accessibility.spec.js": "f10bdefdaac2359d1af5d2099cb8e1770bd7ca486362143f663b5c54459d6cab", + "test/browser/auto-playback.spec.js": "39d9258fb808ef42dfbd38836572335a5c759d99cc1b0ecc1b635a2d7cb3b0fe", + "test/browser/builtin-layers.spec.js": "4efa0ebe413cbf0ca9b06074ce73ead337136bc477c4f8fda6665be0504a31eb", + "test/browser/chapter.spec.js": "d1332c5264bea179d4fd4ec3274eb0db28340bffbda3ffd37d80fc6fb636dca2", + "test/browser/components.spec.js": "2be381b052b69baa3b4ae9cf2582593b9d611158e709e056aaa5df3cf969bef4", + "test/browser/declarations.spec.js": "7340de5f8e34f71cf8d7dbf5f428c3e1c20677a44cc5f561199c9e55d21dc44a", + "test/browser/display-mini.spec.js": "eecb351ef6c1b4d5a96c682e9d9b4507260473b10159bad0b918af277c2c58f3", + "test/browser/display-native.spec.js": "557f0613a23c8da819d55a62acd5ae47340f16cfb4f91bb9778f7984b8887e49", + "test/browser/display-orientation.spec.js": "754bb231c4ef3f634235269aed0588d118ccc9bcbb1bd734f4356cd4222119a8", + "test/browser/display-pip-webkit.spec.js": "8169cee87dad40ecc4b1c1b0dbf2a6667e0b54197f889cfb4f8b3044cdd703cf", + "test/browser/display-pip.spec.js": "562f25b2e27c4644981d5e95f54bdc1a887ec051a10fe5e91ccad3ae22c8238d", + "test/browser/display-sizing.spec.js": "04912463007d1fa53a5d5048a88e7fcb9c0238a4e20e215e11a3dfe381ad74da", + "test/browser/display-video-fullscreen.spec.js": "961b21a5965d230e8ab8d7cdf7c72914c8c5f9526408a83ff0552cc263225ccb", + "test/browser/display-web.spec.js": "50bdbbb4988e47e34a4cbb08184a68b0000e2dcf34bf60192267648045b3aca0", + "test/browser/dom-boundaries.spec.js": "3edeeaed4f642cf2efca29a7b2905dca98bfb1e6527e9053c59a0f9b374a7091", + "test/browser/editor-types.spec.js": "11303e272c1a5202ffc1c192ddc70ef3e988c9ec78b4d4dd4936c3c8a7b6636f", + "test/browser/emitter.spec.js": "abf5a850835d1a5580d611a0777c0cdf225a6aa796a63b58096f8646007e5870", + "test/browser/event-scheduling.spec.js": "4ebd5dab23ca8e49580bd1dc3234e612cbae36b735c7c9401d168059eae11c5c", + "test/browser/fast-forward.spec.js": "5b884fae1cd48cb592c2004a8149890aed4741ac0a92b1e415e47b94411bb368", + "test/browser/fixtures.js": "313414b8958eb5b03a2da8595fa0bbf6bfdc01484373898c6cb7179545df175d", + "test/browser/gesture.spec.js": "9301a91220e5cccf1023918580111bf5287f811a51c0b51e7ed71797cb018575", + "test/browser/global-events.spec.js": "67ef2bc32419f17bb10ff40f7d9e542c110f2202028e5a17d58780e2cc6cf5f3", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c", + "test/browser/initialization.spec.js": "cf85dfc88faf2c43b885bf1438b53dbcb4116dc445fc49e8f107bd78ccaa467c", + "test/browser/input-closeout.spec.js": "6ede540965e404c58cf71a23dabb6be9ab2b107e75d5937e6d63b11dbf11cf98", + "test/browser/lifecycle.spec.js": "7726535769bdf01a57d15d562bad9b3bb2cce0d979b7b0def6cbcf77bd72f453", + "test/browser/listener-registry.spec.js": "54c40eebcd818342e92f875cb639d31d1fa0a0fc95897de2cbfbbd4df793ac94", + "test/browser/media-events.spec.js": "3f5c719facfb97498e6f254117fc4d7d2d91e7f0d53efeab6d877e107dac174b", + "test/browser/media-hosts.spec.js": "543e974f5bb89116a688defb2c1e4afdc72bb6cf4b1bf9838d0e837e661d7845", + "test/browser/notice.spec.js": "2b57c1307aace558aae0c4d8d4434a473780eb9d70c6cf62962147f476bdc94b", + "test/browser/options.spec.js": "17733db5056f04f829ecaa925b021d339d0f6f6960cfb8bd277c68cf8c4e119a", + "test/browser/playback-properties.spec.js": "14e0774bf272cca78d203fef9c343b9b2eac5c30ffbe5c354b00640e1cd9627c", + "test/browser/playback.spec.js": "5cc5df6f3968f3e834a6b2bc2c76c3c1c4ec5e7bda5ee3e99aa7394d24ac7e18", + "test/browser/plugins.spec.js": "526c58db1ae2080cf76a13b542e502b4847b23f07e8cd012f40129dda3358a00", + "test/browser/pointer-events.spec.js": "fa789898942d6eeffcb1f8867af46abcdb1dc8a515470ffdb18e89e8fafc4985", + "test/browser/progress-quality.spec.js": "824596e3f0f1a7d8304ca7fed38de4f00b2f967eb87fd48346ad714fbb2e280f", + "test/browser/prompt-components.spec.js": "2513a31306bb17b713aca2f9bc44f045ce34ac547482b4507955b0f1f14484ed", + "test/browser/resource-scope.spec.js": "0196bd9943c1ce2f6560f87156cd0de47606579c1a736bd46d4943179a121d3f", + "test/browser/runtime-types.spec.js": "7ec0442c3cd5a9cad8cc581a11038c85ef9bf85b473198dd4a94e62a77856c8e", + "test/browser/screenshot.spec.js": "a2b49fbd8616533fc351892c1f6687d588d2bc9350fda4be5475decb97d77a0e", + "test/browser/setting-interaction.spec.js": "030266515b16e1bf8677b30e7748f6a6451b10eba541c5ead9a54b5e57bb05b6", + "test/browser/setting-ownership.spec.js": "ef345200701ef826faa7c3aca564726bc9fad6587cc0af091c579d78ee7f3b4e", + "test/browser/setting-update.spec.js": "2f61a9790ebbdb0f3d86adfc2f9bce5e789806af2517403a47d5c02f1eddd1b1", + "test/browser/setting.spec.js": "19acfd07cb6316381e3bce61e0ae284303aeafc8fca14e1657d73568553c5bb6", + "test/browser/source.spec.js": "8bbd3b0eba2dda89f8b5f484468e916a34e2e53319f3ed3106116db51436ffd1", + "test/browser/subtitle-lifecycle.spec.js": "ba91719ccdc9e539aee252d80deaba622fd6e5cb30cdd74697658af1e49dfd58", + "test/browser/template-resources.spec.js": "993ce9876ae9d49f291af4173ffa34276f9b8972828e8d42b8789c5ee512ac6d", + "test/browser/thumbnails.spec.js": "bc00e6fe6eb6987bd36193f26c69e2377249b53f41dfc1474dd44d6e833a2c09", + "test/browser/utils.spec.js": "e7f1739938791a6d19ec2cdf544f57c69ad7caaaa6f379128b3676d73d8611b1" + }, + "tooling": { + "docs/assets/ts/artplayer.d.ts": "652c0fdf605e87203526777a05851bd69c95c1660d5ff29eab19c00967c9a985", + "package.json": "315746ada69ccb62b8b8c10016b3e467667db9e39518b32dc8036cbade662ea4", + "playwright.config.js": "df2384f5626252ec933725867e400ec22eb92bc5e6f04873059b32decf2f2d56", + "yarn.lock": "b3bbf61c78e21fb80ffa53afee663a192ac8085a11359fd42dcd3e6df2f0e022" + }, + "ci": { + "passed": 468, + "productionTypeScript": 249, + "logSha256": "0556d84a9952b0f99bfb05e7e31c65739aff98ab70cde5a38a8cee3ca9b9a263" + }, + "packageOutput": "refactor/.cache/packages/run-4QYvJQ", + "packages": [ + { + "name": "artplayer", + "version": "5.4.1", + "archive": "artplayer.tgz", + "sha256": "d40ad6db7399976aebd5e5089d9c51f54c8f35de84cd51437590cd833624f843", + "files": { + "package/ARCHITECTURE.md": "92e25db4ffb032f12c7bbf8ffe2726cab276aec2eb3074068c7082f3bf18dbae", + "package/README.md": "1e185e65f67fc2081b4182bbc6c4558ea05b6e3fa3acc5dd0c3ac7df1d542b09", + "package/THIRD_PARTY_NOTICES": "b77b5b46b79fa0cda850b0781f78c3b1112c4ed9672fa291956fe8eff53098e7", + "package/dist/artplayer.cts": "0e91e907d021db02a68004603e6190505fdc0806d873ebb6af171aa089a81da7", + "package/dist/artplayer.js": "cb6a785aa6214977bb89afbc63478150e0260fb52274500355b5a3ce386cf17e", + "package/dist/artplayer.legacy.js": "22bcb37a8cadb00e9ba9982704b39e396bbd41262c0dd9c5f327bfe497e0fc87", + "package/dist/artplayer.mjs": "8af16a3e4181ad489c8329443127293c19acd0e733d0a859ad8260f3eebaa244", + "package/dist/artplayer.mts": "f6292596a9ccb1d43a6d6a12c35f859b1889ad15924c5ae0f9f280941aade313", + "package/dist/artplayer.ts": "26a42ac66811e70f68a8ebe62cbf304eb1993451b3e658961be98e7106162527", + "package/dist/component.ts": "aa1c43be67322781b4b355b143bc69d9f29d22e578e4974d6a13e957a7c0334f", + "package/dist/config.ts": "c4fd8681bf32b10c743e3e561c532520c8f32e43fd765524850b15e55cb91c72", + "package/dist/cssVar.ts": "e027d82fb4f01c9ce7559cf679b2d5ee1962d3f7e5b4dd64ca21f472b933efb6", + "package/dist/emitter.ts": "9c62551cdcc6dd3966bed8a7a85dd477435db977c91a294d2ac8f162f9592537", + "package/dist/events.ts": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "package/dist/i18n.ts": "34b0c684668044f7600c80b9d3979f8fb730138007b7cb4e7034326b340156fb", + "package/dist/i18n/ar.js": "bd0bef65f4f7dc3f8ed562904cc6fa9071ff4537fb64c1e0fc3d554141bcd3cb", + "package/dist/i18n/ar.mjs": "59310b7bbeea83bbb7d73aadc5ca82a6ec269c3530d19aa741c94d5c64fc5da8", + "package/dist/i18n/cs.js": "6e2c93daba24c2e48dfa206bcf4f2f2a8a02713b856e404d2e4e4ecd8309ca2f", + "package/dist/i18n/cs.mjs": "c73fba18797d62d7b2581e67fe7340c35fe84510b2250ff1ecaad253d9cabbac", + "package/dist/i18n/es.js": "f4133ac6ea06b69a474b33c4a1809a4066e2376bb9464a3f3aa8330f01f1944a", + "package/dist/i18n/es.mjs": "1390bca3def2be115e811de337df0a0c3f63998e51359f283023246245c552a7", + "package/dist/i18n/fa.js": "8d3ef2e0f0cc0ea480c2167b6fcb87cdf444e90759c3519e8daa139fec576da4", + "package/dist/i18n/fa.mjs": "ab441e8a2d79043b29ceca87c783bf06874bb9d3a149c1604bc167eb481be2a9", + "package/dist/i18n/fr.js": "89dc4194a6c0a962b9ce756b52c90401c1acf3b159f265f3bc0d7d6d7d987f03", + "package/dist/i18n/fr.mjs": "99491878430fb7b6f2b7bf93da0588a831704b412e01116f23ba1d9d45863816", + "package/dist/i18n/id.js": "4c6dc86db741bcc2857df55a9d037e82e91d375fa6fd22e0562809ff621b92db", + "package/dist/i18n/id.mjs": "383e5803a6b6686c6de4e867770241de75b6f517dcca2bdedc6f2004bf6e1fb3", + "package/dist/i18n/pl.js": "3a38828b1c3d719c0aca9906cf6a46c23555a8411f8d57645f0e0ce8147dc664", + "package/dist/i18n/pl.mjs": "079ed96732979035297af387c64a7b99519b5a43107fb86735a654ea4fe8e9b5", + "package/dist/i18n/ru.js": "62fac9dddb302eb16382e6e9301fc4b2c66f5f69d4a358a26b67026a5fa4e787", + "package/dist/i18n/ru.mjs": "a893aeaee1d79409db72e324fbff200e3864f33ed168f04d91d25f7cf2efa765", + "package/dist/i18n/tr.js": "1492c36b069a7d73db4f3913bd18085faff7afd8b3c158138fe264e31600e38c", + "package/dist/i18n/tr.mjs": "a90478cac078836b76c2a98261907610fee07f3e4b28671b8e7dbf533778f918", + "package/dist/i18n/vi.js": "c7216ef7e608a79b7e2c479a07bf310d4ab79577947ac4a62d676faaced0e9cf", + "package/dist/i18n/vi.mjs": "66270fdfa0b5da396322d1769169b7df37a030ba15ac18eb30bd87b3af8074ec", + "package/dist/i18n/zh-tw.js": "11c49857d6d40a5ffd224ffa59c9026e71621b345f63c5a086326db80a22371a", + "package/dist/i18n/zh-tw.mjs": "a38e630cb96de96c15d824686aec750e25cf6c8ada01285a292442a81566314f", + "package/dist/icons.ts": "0d8e8e52e52130dd4a29bab551dd7a2a954797e42e92a6e068c85d583e23e6a4", + "package/dist/language.cts": "2248040d86a8e34626755c4ecf53ea0174706c653073cf0e15884a030d173120", + "package/dist/language.mts": "c391e863012c77769e661afbf8fa949e9373aa88d17f58cbba7f5696edb8077f", + "package/dist/legacy/language.ts": "c452ffd764ff9b29b819b3475c42395d2ea7a33560d8c186ef5df3844b9524c3", + "package/dist/option.ts": "850e5264219b8b438c80694402225b690b131786677a5da0d22739ec2352d263", + "package/dist/playback.ts": "1ceaed3aa1cef511fe8b20f4874647f6065c723ad805b742a0a9247e16bb1bb5", + "package/dist/player.ts": "f1e50257df2ea592d0a0e1f36078dda77eaf2cf3b3d795307501396562d99f28", + "package/dist/plugin.ts": "2a57e148fda00ee687da5036b890b0f611cb94bb403a1ed52602179060259d35", + "package/dist/quality.ts": "7ed6ed78cea52991b2f6ddd2bd3b7bd8c5146fdfff7486fe8b814c3e632f1567", + "package/dist/runtime.cts": "52cfff1daeb6841a90212c8fa8d46ca46d6650bb7ed1b59b62115d854b8ad652", + "package/dist/runtime.mts": "1b09bc0ee0f0ee2f788689eaff441bdeda1fab0ce783e71b61b9792d81072b03", + "package/dist/runtime.ts": "ec4b1d56993eb482a77eb0f94b701047549d009e6ba6433f27e7d464fef30c2b", + "package/dist/runtime/component.ts": "840213299c942fe058eb5436977ceec066b9dccda24c55ae9f464b399c979e39", + "package/dist/runtime/construction.ts": "24cc5cda1f614314db382271a9b0d5583b781894cfdf6c548700b1b5270467ee", + "package/dist/runtime/events.ts": "52848f57d35eb1037cf74c8877521edf99a015bcd77f30ef6bbcba1807a99bfe", + "package/dist/runtime/media.ts": "8828f80953aec3e95328cefe691661e8897cb27cb309483cf806ec45a8549ae3", + "package/dist/runtime/option.ts": "bb672e49ffe74a6fc78543217f6de80d7d738890146df0857c709d4dc283e4ce", + "package/dist/runtime/player.ts": "a4a24794e26cfb9e4310bf0f459a7a407e85bf81b4f3a4feb6294331af8036fb", + "package/dist/runtime/plugin.ts": "9ad482f2a77914a91450419680b8af6b314b926f0831c2f7f6d7c466690f95c9", + "package/dist/runtime/services.ts": "8e4648d8c61bff47343f9e1c2b995af69fc00947264b826109ceadcbaf553254", + "package/dist/runtime/setting.ts": "c48d20957b57f79f985ef76a2950cc8a5cfa25dafa8ec5939e562661778e6218", + "package/dist/runtime/subtitle.ts": "13241c4f9a87517aa2cf7b3e0bb8cedaa12fa0b4d3f8934285797583b752557e", + "package/dist/runtime/template.ts": "da9975513a1938e7f386f4f65f718f0fc595164bfeac8f0cd99a3e97a54919a1", + "package/dist/runtime/utils.ts": "cab9916f5224a3b047812b9f759cc9cc62105662599744067a6955020ab36916", + "package/dist/setting.ts": "d12a75b656fff70cbb30be4bffec46d9c4273636e8722bce971a4d2b188712a1", + "package/dist/subtitle.ts": "d25b470e47d6a9bd696d9c1ad8adb58e56a208f05695186d513bc8c43c2e8acf", + "package/dist/template.ts": "68aed9e97d006d6be4fabb8504ca84dafab770b0925f4d6e7319e67c82f21b0d", + "package/dist/utils.ts": "494ec447ab467a07ddd7a2c2abf778b3fce69fd28a09aaa8ced9759f8de2e3f6", + "package/package.json": "82e92699e7c29847f32ac6767ece0401290e7d7a12854722bdbcfd09b90b7954", + "package/types/COMPATIBILITY.md": "a7da9e102a116104b513df4f7451247b7759bc502d3375f30bd5b14a541826e0", + "package/types/README.md": "1bd9868e773610e6312fd48a1c5aa20772d29df0af40c3db66e75b7ab4a1aee0", + "package/types/artplayer.d.cts": "3685065e4263abcfd9d953176e461d5b3eb990b0363b54689a7f55deba770fef", + "package/types/artplayer.d.mts": "b664fec51ee5c5381f2ceab25d99d52aee56feab04a2ee7b4ea5b2145ea5fa0e", + "package/types/artplayer.d.ts": "5d0162adf7ac6d0f2bb9b5cfe361f28657c4d9c540cadbf36eba3cc954ce50f8", + "package/types/component.d.ts": "ae5bc1ddeaa1ee1ebbc62573e32423993727079205c64751a5a314170e588a32", + "package/types/config.d.ts": "36f9a84cd436f17701a0d11d3417fc1fe0414e0c52c80083b94a85dfc329e37e", + "package/types/cssVar.d.ts": "93217860fff2ebf750f606d95ddd22220a58837119e63bdf2f5f78fd7488458b", + "package/types/emitter.d.ts": "7e1f9a2a8ce65feb95734f1ed52d1334e57aa388bbef2a43d8bc53a9b6f6623c", + "package/types/events.d.ts": "f83624c9268a284477e8bd793fe3562a2363b72f2a44d5c64fe8c6a6cede8830", + "package/types/i18n.d.ts": "f4f2f05bdfda73c74fef34767cb18ee8e11b743120b1c4598e9714d7846018e5", + "package/types/icons.d.ts": "326a67ba7bdcf52862c5b2a269e540140aff98d05c7b96196485a77f84fe5960", + "package/types/language.d.cts": "f7928e108cf7b7814c2d75cb0a525333e95873fca6cd6d89a740450656b9c1cd", + "package/types/language.d.mts": "6619a26d604b7cccbe2f596243d87ae37cfaae33b8b52874ec071d9787446f9e", + "package/types/legacy/language.d.ts": "c7abda4d506fd933c350e9030290bf9e64347a921d683a66115da1995ebe0a81", + "package/types/option.d.ts": "ccf2c8ddc537dc65c9682d39f044726e23bff18f476b622512d7e6a4b949b5f6", + "package/types/playback.d.ts": "58705c273df6e76a77a6575e769a9ec6c013785c25080f2551aa22415788d870", + "package/types/player.d.ts": "92b00211b70ac71336e495899df972a0519dd138111846044fe4e0f967966177", + "package/types/plugin.d.ts": "fc3594a41c51d8248713e33c486fb1f6a518ac5c7ce31be6988a6cd8d052c5f3", + "package/types/quality.d.ts": "1ac1a48b4f74ff9ba1ce60443e1463d50d1c6a2e5d87d63dc7d2a8eb7f4c2c34", + "package/types/runtime.d.cts": "7ee988dfea9a0ac71a34a656f96f7b74e78aa92547cfdfab7ff7e1139a77d4a3", + "package/types/runtime.d.mts": "dcb85f59a8b7714918ced0c1d18c2bb24e8b80b56d8c594e019dcbdb5ad88b08", + "package/types/runtime.d.ts": "9c6ccd39a1be293f17ae46dae8ea077053e12635ee79d73a5e3b3a559230fcff", + "package/types/runtime/component.d.ts": "1b4c0cee44568649e80140fe778febfcae88af0ac85515f1cbeff78ab0c6d14f", + "package/types/runtime/construction.d.ts": "7a87bedf6f7ffff0c46078aa5f1551e0077d35574e286516121f5f935e2d9ce4", + "package/types/runtime/events.d.ts": "a1e2f9d387475453eaf95c2a5ee79e228636c0bb859bda3fcc46da46574a0c31", + "package/types/runtime/media.d.ts": "8fc89401be7fe25542c169d07dd5675f10916ed20be8493e19695966cf3864a8", + "package/types/runtime/option.d.ts": "6e334e1a76fdcc40b4665c02523bd31c3994d96078fadeb40e23422aa54c1a1d", + "package/types/runtime/player.d.ts": "8ac6383502e4872e83659838844856903031a81a0adc8e8535feb78453aa042c", + "package/types/runtime/plugin.d.ts": "8528f2b17843149f42f9cc16d6fd70baa238c9dc2c329b67d2c38096799c69bd", + "package/types/runtime/services.d.ts": "604c9f8e4b6c0da818f96576bf9f4b0e96085a9003927b2f7ba30027b1ba237e", + "package/types/runtime/setting.d.ts": "349c1fcb205ad312916bd3ee55e6bf241ea8a569fb2ab6c80822e69fc518f7d7", + "package/types/runtime/subtitle.d.ts": "269ff84678d327b3a9dc2f5bc6cc0d731d1e081b85422e474621d5d792efb153", + "package/types/runtime/template.d.ts": "7a62f968a38b4bf9109a4439557c02074eb1d62ba1f6e21a8eb194e91f0badfe", + "package/types/runtime/utils.d.ts": "6bf731705d86853e066dbaf3b8d4003b6548423fe615b7412b722bd0d3a6e48b", + "package/types/setting.d.ts": "08305a75dff96f06490430e099338b463df471b550c1d0dac3abc8995b39eb09", + "package/types/subtitle.d.ts": "b18314e2d64efdb6045830b6e12f615ae2ed585416130e562329ad3ea337f6ce", + "package/types/template.d.ts": "4792bc0c2cbcb7966e4375118bd34b326166e0831862e94ace4cf6b1bbe6a8c8", + "package/types/utils.d.ts": "fca0d3d814df94a25f9eb067c86fa0cf272e2791bac793b91229d57680797712" + } + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "archive": "artplayer-plugin-chapter.tgz", + "sha256": "5be9d4d0b5bb2464c623cd972796b9acd3579d00e006a3567312690d4b871e47", + "files": { + "package/ARCHITECTURE.md": "20743bad87a174b0450e0d876b6aa6b2a9f47df296d479511ce7cc9298fdb57c", + "package/README.md": "b95400ff3d525621a15268bb56a2d353aacaaadefde7e735d7abd91a34edd96f", + "package/dist/artplayer-plugin-chapter.js": "6ac3dfe28f46084ac7caedd571b1a97dcee3cf9d708112f1b8bbd6566e1dc5c5", + "package/dist/artplayer-plugin-chapter.legacy.js": "6d9bff885412169e701670961aa00c2e46c4b42c9b9647ff4e6d198777d2a359", + "package/dist/artplayer-plugin-chapter.mjs": "26415cecab2c0198c566cef0232e20123413782d5bad7534a32939b3298617af", + "package/package.json": "24eec6907b3218439189adab6af3f932c1497c47c2d41209311c01042b07fd4f", + "package/types/artplayer-plugin-chapter.d.cts": "4f07514b37453cd6cea8e5aa28fa018ff31738e0d423c11a3b5eccd50ed30bcc", + "package/types/artplayer-plugin-chapter.d.mts": "610179754db36276e161a07bccf4eaba8b4480f053e716a2bcc5a1574871a171", + "package/types/artplayer-plugin-chapter.d.ts": "581aa2862e709601c87a23585f54a969ebd350be56a7469a31ff53f1311b578d" + } + } + ], + "runtime": { + "checks": [ + "DIST.cjs", + "DIST.cjs-legacy", + "DIST.esm", + "DIST.esm-default-only", + "DIST.esm-legacy", + "DIST.runtime-cjs-identity", + "DIST.runtime-esm-identity", + "DIST.runtime-legacy-identity", + "DIST.runtime-shared-statics", + "DIST.runtime-types-only", + "DIST.global-core", + "DIST.amd-core", + "DIST.global-core-legacy", + "DIST.amd-core-legacy", + "DIST.global-chapter", + "DIST.amd-chapter", + "DIST.global-chapter-legacy", + "DIST.amd-chapter-legacy", + "SSR.import-template", + "SSR.constructor-browser-only", + "SSR.custom-ua-umd-legacy", + "SSR.custom-ua-esm", + "DIST.i18n-cjs-esm-global", + "DIST.exports-boundary", + "DIST.direct-esm-file", + "EVENT.lazy-registry", + "EVENT.symbol-number-channels", + "EVENT.context-removal", + "EVENT.once-throw-consumed", + "EVENT.chain-context-arguments", + "EVENT.once-reentry", + "EVENT.dispatch-snapshot", + "EVENT.off-original-once", + "EVENT.throw-propagation" + ], + "observations": { + "constructorErrors": [ + { + "useSSR": false, + "name": "Error", + "message": "Artplayer can only be used in the browser environment" + }, + { + "useSSR": true, + "name": "Error", + "message": "Artplayer can only be used in the browser environment" + }, + { + "useSSR": false, + "name": "Error", + "message": "Artplayer can only be used in the browser environment" + }, + { + "useSSR": true, + "name": "Error", + "message": "Artplayer can only be used in the browser environment" + }, + { + "useSSR": false, + "name": "Error", + "message": "Artplayer can only be used in the browser environment" + }, + { + "useSSR": true, + "name": "Error", + "message": "Artplayer can only be used in the browser environment" + } + ], + "customUA": [ + { + "filename": "artplayer.js", + "userAgent": "", + "historicalFailure": false, + "timers": 0 + }, + { + "filename": "artplayer.js", + "userAgent": "Android Chrome", + "historicalFailure": false, + "timers": 0 + }, + { + "filename": "artplayer.js", + "userAgent": "iPhone Safari", + "historicalFailure": false, + "timers": 0 + }, + { + "filename": "artplayer.js", + "userAgent": "Macintosh Safari", + "historicalFailure": false, + "timers": 0 + }, + { + "filename": "artplayer.legacy.js", + "userAgent": "", + "historicalFailure": false, + "timers": 0 + }, + { + "filename": "artplayer.legacy.js", + "userAgent": "Android Chrome", + "historicalFailure": false, + "timers": 0 + }, + { + "filename": "artplayer.legacy.js", + "userAgent": "iPhone Safari", + "historicalFailure": false, + "timers": 0 + }, + { + "filename": "artplayer.legacy.js", + "userAgent": "Macintosh Safari", + "historicalFailure": false, + "timers": 0 + }, + { + "filename": "artplayer.mjs", + "userAgent": "", + "historicalFailure": false + }, + { + "filename": "artplayer.mjs", + "userAgent": "Android Chrome", + "historicalFailure": false + }, + { + "filename": "artplayer.mjs", + "userAgent": "iPhone Safari", + "historicalFailure": false + }, + { + "filename": "artplayer.mjs", + "userAgent": "Macintosh Safari", + "historicalFailure": false + } + ], + "languages": [ + { + "name": "ar", + "globalName": "artplayerI18nAr", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "تشغيل" + }, + { + "name": "cs", + "globalName": "artplayerI18nCs", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "Přehrát" + }, + { + "name": "es", + "globalName": "artplayerI18nEs", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "Reproduciendo" + }, + { + "name": "fa", + "globalName": "artplayerI18nFa", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "پخش" + }, + { + "name": "fr", + "globalName": "artplayerI18nFr", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "Lire" + }, + { + "name": "id", + "globalName": "artplayerI18nId", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "Putar" + }, + { + "name": "pl", + "globalName": "artplayerI18nPl", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "Odtwórz" + }, + { + "name": "ru", + "globalName": "artplayerI18nRu", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "Играть" + }, + { + "name": "tr", + "globalName": "artplayerI18nTr", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "Oynat" + }, + { + "name": "vi", + "globalName": "artplayerI18nVi", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "Phát" + }, + { + "name": "zh-tw", + "globalName": "artplayerI18nZhTw", + "keys": [ + "AirPlay", + "AirPlay Not Available", + "Aspect Ratio", + "Back", + "Close", + "Context Menu", + "Default", + "Exit Fullscreen", + "Exit PIP Mode", + "Exit Web Fullscreen", + "Fullscreen", + "Fullscreen Not Supported", + "Hide Setting", + "Horizontal", + "Jump Play", + "Last Seen", + "Lock", + "Mini Player", + "Mute", + "Normal", + "Open", + "PIP Mode", + "PIP Not Supported", + "Pause", + "Play", + "Play Speed", + "Progress", + "Rate", + "Reconnect", + "Screenshot", + "Settings", + "Show Setting", + "Subtitle Offset", + "Switch Subtitle", + "Switch Video", + "Vertical", + "Video Flip", + "Video Info", + "Video Load Failed", + "Volume", + "Web Fullscreen" + ], + "play": "播放" + } + ], + "blockedDeepImports": [ + { + "specifier": "artplayer/dist/artplayer.js", + "code": "ERR_PACKAGE_PATH_NOT_EXPORTED" + }, + { + "specifier": "artplayer/types/artplayer.d.ts", + "code": "ERR_PACKAGE_PATH_NOT_EXPORTED" + }, + { + "specifier": "artplayer-plugin-chapter/dist/artplayer-plugin-chapter.js", + "code": "ERR_PACKAGE_PATH_NOT_EXPORTED" + }, + { + "specifier": "artplayer/types", + "code": "ERR_PACKAGE_PATH_NOT_EXPORTED" + } + ], + "resolutions": { + "artplayer": "node_modules/artplayer/dist/artplayer.js", + "artplayer/legacy": "node_modules/artplayer/dist/artplayer.legacy.js", + "artplayer-plugin-chapter": "node_modules/artplayer-plugin-chapter/dist/artplayer-plugin-chapter.js", + "artplayer-plugin-chapter/legacy": "node_modules/artplayer-plugin-chapter/dist/artplayer-plugin-chapter.legacy.js" + }, + "api": { + "static": { + "length": { + "enumerable": false, + "configurable": true, + "writable": false, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "name": { + "enumerable": false, + "configurable": true, + "writable": false, + "get": "undefined", + "set": "undefined", + "value": "string" + }, + "prototype": { + "enumerable": false, + "configurable": false, + "writable": false, + "get": "undefined", + "set": "undefined", + "value": "object" + }, + "instances": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "version": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "config": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "utils": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "scheme": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "Emitter": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "validator": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "kindOf": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "html": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "option": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "STYLE": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "string" + }, + "DEBUG": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + }, + "CONTEXTMENU": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + }, + "NOTICE_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "SETTING_WIDTH": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "SETTING_ITEM_WIDTH": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "SETTING_ITEM_HEIGHT": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "RESIZE_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "SCROLL_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "SCROLL_GAP": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "AUTO_PLAYBACK_MAX": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "AUTO_PLAYBACK_MIN": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "AUTO_PLAYBACK_TIMEOUT": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "RECONNECT_TIME_MAX": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "RECONNECT_SLEEP_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "CONTROL_HIDE_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "DBCLICK_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "DBCLICK_FULLSCREEN": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + }, + "MOBILE_DBCLICK_PLAY": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + }, + "MOBILE_CLICK_PLAY": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + }, + "AUTO_ORIENTATION_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "INFO_LOOP_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "FAST_FORWARD_VALUE": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "FAST_FORWARD_TIME": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "TOUCH_MOVE_RATIO": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "VOLUME_STEP": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "SEEK_STEP": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "PLAYBACK_RATE": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "object" + }, + "ASPECT_RATIO": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "object" + }, + "FLIP": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "object" + }, + "FULLSCREEN_WEB_IN_BODY": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + }, + "LOG_VERSION": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + }, + "USE_RAF": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + }, + "REMOVE_SRC_WHEN_DESTROY": { + "enumerable": true, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "boolean" + } + }, + "prototype": { + "constructor": { + "enumerable": false, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "function" + }, + "proxy": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "query": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "video": { + "enumerable": false, + "configurable": true, + "get": "function", + "set": "undefined", + "value": "undefined" + }, + "reset": { + "enumerable": false, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "function" + }, + "destroy": { + "enumerable": false, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "function" + } + }, + "emitter": { + "constructor": { + "enumerable": false, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "function" + }, + "on": { + "enumerable": false, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "function" + }, + "once": { + "enumerable": false, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "function" + }, + "emit": { + "enumerable": false, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "function" + }, + "off": { + "enumerable": false, + "configurable": true, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "function" + } + }, + "factory": { + "length": { + "enumerable": false, + "configurable": true, + "writable": false, + "get": "undefined", + "set": "undefined", + "value": "number" + }, + "name": { + "enumerable": false, + "configurable": true, + "writable": false, + "get": "undefined", + "set": "undefined", + "value": "string" + }, + "prototype": { + "enumerable": false, + "configurable": false, + "writable": true, + "get": "undefined", + "set": "undefined", + "value": "object" + } + }, + "defaults": { + "id": "", + "container": "#artplayer", + "url": "", + "poster": "", + "type": "", + "theme": "#f00", + "volume": 0.7, + "isLive": false, + "muted": false, + "autoplay": false, + "autoSize": false, + "autoMini": false, + "loop": false, + "flip": false, + "playbackRate": false, + "aspectRatio": false, + "screenshot": false, + "setting": false, + "hotkey": true, + "pip": false, + "mutex": true, + "backdrop": true, + "fullscreen": false, + "fullscreenWeb": false, + "subtitleOffset": false, + "miniProgressBar": false, + "useSSR": false, + "playsInline": true, + "lock": false, + "gesture": true, + "fastForward": false, + "autoPlayback": false, + "autoOrientation": false, + "airplay": false, + "layers": [], + "contextmenu": [], + "controls": [], + "settings": [], + "quality": [], + "highlight": [], + "plugins": [], + "thumbnails": { + "url": "", + "number": 60, + "column": 10, + "width": 0, + "height": 0, + "scale": 1 + }, + "subtitle": { + "url": "", + "type": "", + "style": {}, + "name": "", + "escape": true, + "encoding": "utf-8", + "onVttLoad": "$function" + }, + "moreVideoAttr": { + "controls": false, + "preload": "metadata" + }, + "i18n": {}, + "icons": {}, + "cssVar": {}, + "customType": {}, + "lang": "zh-cn" + } + } + } + }, + "types": [ + { + "compiler": "5.9.3", + "mode": "node10-commonjs", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/legacy/language.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.9.3", + "mode": "nodenext-cjs", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/language.d.cts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.9.3", + "mode": "bundler-esm", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.mts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.mts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/language.d.cts", + "node_modules/artplayer/types/language.d.mts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "4.3.5", + "mode": "node10-commonjs", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-compat/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/legacy/language.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.9.3", + "mode": "nodenext-esm", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.mts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.mts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/language.d.cts", + "node_modules/artplayer/types/language.d.mts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + } + ], + "preciseTypes": [ + { + "compiler": "5.9.3", + "mode": "node10-commonjs", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/runtime.d.ts", + "node_modules/artplayer/types/runtime/component.d.ts", + "node_modules/artplayer/types/runtime/construction.d.ts", + "node_modules/artplayer/types/runtime/events.d.ts", + "node_modules/artplayer/types/runtime/media.d.ts", + "node_modules/artplayer/types/runtime/option.d.ts", + "node_modules/artplayer/types/runtime/player.d.ts", + "node_modules/artplayer/types/runtime/plugin.d.ts", + "node_modules/artplayer/types/runtime/services.d.ts", + "node_modules/artplayer/types/runtime/setting.d.ts", + "node_modules/artplayer/types/runtime/subtitle.d.ts", + "node_modules/artplayer/types/runtime/template.d.ts", + "node_modules/artplayer/types/runtime/utils.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.9.3", + "mode": "nodenext-cjs", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/runtime.d.cts", + "node_modules/artplayer/types/runtime.d.ts", + "node_modules/artplayer/types/runtime/component.d.ts", + "node_modules/artplayer/types/runtime/construction.d.ts", + "node_modules/artplayer/types/runtime/events.d.ts", + "node_modules/artplayer/types/runtime/media.d.ts", + "node_modules/artplayer/types/runtime/option.d.ts", + "node_modules/artplayer/types/runtime/player.d.ts", + "node_modules/artplayer/types/runtime/plugin.d.ts", + "node_modules/artplayer/types/runtime/services.d.ts", + "node_modules/artplayer/types/runtime/setting.d.ts", + "node_modules/artplayer/types/runtime/subtitle.d.ts", + "node_modules/artplayer/types/runtime/template.d.ts", + "node_modules/artplayer/types/runtime/utils.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.9.3", + "mode": "bundler-esm", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.mts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.mts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/runtime.d.cts", + "node_modules/artplayer/types/runtime.d.mts", + "node_modules/artplayer/types/runtime.d.ts", + "node_modules/artplayer/types/runtime/component.d.ts", + "node_modules/artplayer/types/runtime/construction.d.ts", + "node_modules/artplayer/types/runtime/events.d.ts", + "node_modules/artplayer/types/runtime/media.d.ts", + "node_modules/artplayer/types/runtime/option.d.ts", + "node_modules/artplayer/types/runtime/player.d.ts", + "node_modules/artplayer/types/runtime/plugin.d.ts", + "node_modules/artplayer/types/runtime/services.d.ts", + "node_modules/artplayer/types/runtime/setting.d.ts", + "node_modules/artplayer/types/runtime/subtitle.d.ts", + "node_modules/artplayer/types/runtime/template.d.ts", + "node_modules/artplayer/types/runtime/utils.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.9.3", + "mode": "nodenext-esm", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2016.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.mts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.mts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/runtime.d.cts", + "node_modules/artplayer/types/runtime.d.mts", + "node_modules/artplayer/types/runtime.d.ts", + "node_modules/artplayer/types/runtime/component.d.ts", + "node_modules/artplayer/types/runtime/construction.d.ts", + "node_modules/artplayer/types/runtime/events.d.ts", + "node_modules/artplayer/types/runtime/media.d.ts", + "node_modules/artplayer/types/runtime/option.d.ts", + "node_modules/artplayer/types/runtime/player.d.ts", + "node_modules/artplayer/types/runtime/plugin.d.ts", + "node_modules/artplayer/types/runtime/services.d.ts", + "node_modules/artplayer/types/runtime/setting.d.ts", + "node_modules/artplayer/types/runtime/subtitle.d.ts", + "node_modules/artplayer/types/runtime/template.d.ts", + "node_modules/artplayer/types/runtime/utils.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.1.6", + "mode": "node10-commonjs", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/runtime.d.ts", + "node_modules/artplayer/types/runtime/component.d.ts", + "node_modules/artplayer/types/runtime/construction.d.ts", + "node_modules/artplayer/types/runtime/events.d.ts", + "node_modules/artplayer/types/runtime/media.d.ts", + "node_modules/artplayer/types/runtime/option.d.ts", + "node_modules/artplayer/types/runtime/player.d.ts", + "node_modules/artplayer/types/runtime/plugin.d.ts", + "node_modules/artplayer/types/runtime/services.d.ts", + "node_modules/artplayer/types/runtime/setting.d.ts", + "node_modules/artplayer/types/runtime/subtitle.d.ts", + "node_modules/artplayer/types/runtime/template.d.ts", + "node_modules/artplayer/types/runtime/utils.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.1.6", + "mode": "nodenext-cjs", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/runtime.d.cts", + "node_modules/artplayer/types/runtime.d.ts", + "node_modules/artplayer/types/runtime/component.d.ts", + "node_modules/artplayer/types/runtime/construction.d.ts", + "node_modules/artplayer/types/runtime/events.d.ts", + "node_modules/artplayer/types/runtime/media.d.ts", + "node_modules/artplayer/types/runtime/option.d.ts", + "node_modules/artplayer/types/runtime/player.d.ts", + "node_modules/artplayer/types/runtime/plugin.d.ts", + "node_modules/artplayer/types/runtime/services.d.ts", + "node_modules/artplayer/types/runtime/setting.d.ts", + "node_modules/artplayer/types/runtime/subtitle.d.ts", + "node_modules/artplayer/types/runtime/template.d.ts", + "node_modules/artplayer/types/runtime/utils.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.1.6", + "mode": "bundler-esm", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.mts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.mts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/runtime.d.cts", + "node_modules/artplayer/types/runtime.d.mts", + "node_modules/artplayer/types/runtime.d.ts", + "node_modules/artplayer/types/runtime/component.d.ts", + "node_modules/artplayer/types/runtime/construction.d.ts", + "node_modules/artplayer/types/runtime/events.d.ts", + "node_modules/artplayer/types/runtime/media.d.ts", + "node_modules/artplayer/types/runtime/option.d.ts", + "node_modules/artplayer/types/runtime/player.d.ts", + "node_modules/artplayer/types/runtime/plugin.d.ts", + "node_modules/artplayer/types/runtime/services.d.ts", + "node_modules/artplayer/types/runtime/setting.d.ts", + "node_modules/artplayer/types/runtime/subtitle.d.ts", + "node_modules/artplayer/types/runtime/template.d.ts", + "node_modules/artplayer/types/runtime/utils.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + }, + { + "compiler": "5.1.6", + "mode": "nodenext-esm", + "diagnostics": [], + "declarations": [ + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.decorators.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.decorators.legacy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.dom.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.collection.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.core.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.generator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.iterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.proxy.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.reflect.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2015.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2016.array.include.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2016.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2017.typedarrays.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.asyncgenerator.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.asynciterable.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2018.regexp.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.array.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.object.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2019.symbol.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.bigint.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.date.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.intl.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.number.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.promise.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.sharedmemory.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.string.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es2020.symbol.wellknown.d.ts", + "D:/github/ArtPlayer/node_modules/typescript-runtime-compat/lib/lib.es5.d.ts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.cts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.mts", + "node_modules/artplayer-plugin-chapter/types/artplayer-plugin-chapter.d.ts", + "node_modules/artplayer/types/artplayer.d.cts", + "node_modules/artplayer/types/artplayer.d.mts", + "node_modules/artplayer/types/artplayer.d.ts", + "node_modules/artplayer/types/component.d.ts", + "node_modules/artplayer/types/config.d.ts", + "node_modules/artplayer/types/cssVar.d.ts", + "node_modules/artplayer/types/emitter.d.ts", + "node_modules/artplayer/types/events.d.ts", + "node_modules/artplayer/types/i18n.d.ts", + "node_modules/artplayer/types/icons.d.ts", + "node_modules/artplayer/types/option.d.ts", + "node_modules/artplayer/types/playback.d.ts", + "node_modules/artplayer/types/player.d.ts", + "node_modules/artplayer/types/plugin.d.ts", + "node_modules/artplayer/types/quality.d.ts", + "node_modules/artplayer/types/runtime.d.cts", + "node_modules/artplayer/types/runtime.d.mts", + "node_modules/artplayer/types/runtime.d.ts", + "node_modules/artplayer/types/runtime/component.d.ts", + "node_modules/artplayer/types/runtime/construction.d.ts", + "node_modules/artplayer/types/runtime/events.d.ts", + "node_modules/artplayer/types/runtime/media.d.ts", + "node_modules/artplayer/types/runtime/option.d.ts", + "node_modules/artplayer/types/runtime/player.d.ts", + "node_modules/artplayer/types/runtime/plugin.d.ts", + "node_modules/artplayer/types/runtime/services.d.ts", + "node_modules/artplayer/types/runtime/setting.d.ts", + "node_modules/artplayer/types/runtime/subtitle.d.ts", + "node_modules/artplayer/types/runtime/template.d.ts", + "node_modules/artplayer/types/runtime/utils.d.ts", + "node_modules/artplayer/types/setting.d.ts", + "node_modules/artplayer/types/subtitle.d.ts", + "node_modules/artplayer/types/template.d.ts", + "node_modules/artplayer/types/utils.d.ts" + ] + } + ], + "install": { + "refactor/.cache/packages/run-4QYvJQ/consumer-yarn.lock": "4891b77135bf1a94323b5c8e6498537d8818fdf8ed96a4887343709feedfc2e0", + "refactor/.cache/packages/run-4QYvJQ/frozen-install.log": "6d8a95fad69ac94a55d176b472fc3a0f72783092e49b7e683156b6717510f4a8", + "refactor/.cache/packages/run-4QYvJQ/install.log": "c3b09f4c65bfb4a1bf31ddd2e3328c22988cf52a31e36c31ea2de4d3132a89c6", + "refactor/.cache/packages/run-4QYvJQ/report.json": "07ca6c6799d289a874c04d508e67f7ed1184f359c1be9048229bf14997dd0d9e" + }, + "buildAndImportLogs": { + "refactor/.cache/core23-build-i18n.log": "ad1ba09a85c11eae0985023a541950cbe61b42fd9813c56b0cf9f19a0e0aa6ba", + "refactor/.cache/core23-build.log": "976b90ca44adf75b030f167f018c8f2d2d87b1c1b6d163ab542c4b7f81785ad8", + "refactor/.cache/core23-imports.log": "a7c8a0298bc574dc790d37b8363bea3327ca0e7433091e7334f9b8d5a6b346d8" + }, + "browser": [ + { + "variant": "modern", + "stats": { + "startTime": "2026-09-11T12:48:42.855Z", + "duration": 443249.14900000003, + "expected": 1749, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "counts": { + "chromium": 583, + "firefox": 583, + "webkit": 583 + }, + "nativePipCapabilities": [ + { + "engine": "chromium", + "standard": true, + "webkit": false + }, + { + "engine": "firefox", + "standard": true, + "webkit": false + }, + { + "engine": "webkit", + "standard": false, + "webkit": false + }, + { + "engine": "chromium", + "enabled": true, + "request": true, + "exit": true + }, + { + "engine": "firefox", + "enabled": true, + "request": true, + "exit": true + }, + { + "engine": "webkit", + "enabled": false, + "request": false, + "exit": false + } + ], + "cases": [ + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen keyboard activation retains focus through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen external exit preserves the current in-player focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: PiP keyboard control follows real native capability without a second playback action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: SSR retains native nodes while keyboard controls toggle real subtitle cues and survive fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen keyboard activation retains focus through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen external exit preserves the current in-player focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: PiP keyboard control follows real native capability without a second playback action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: SSR retains native nodes while keyboard controls toggle real subtitle cues and survive fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen keyboard activation retains focus through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen external exit preserves the current in-player focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: PiP keyboard control follows real native capability without a second playback action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: SSR retains native nodes while keyboard controls toggle real subtitle cues and survive fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is hidden", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is disabled", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting navigation ignores hidden rows and inert descendants", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is hidden", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is disabled", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting navigation ignores hidden rows and inert descendants", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is hidden", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is disabled", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting navigation ignores hidden rows and inert descendants", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "published: DOM utilities preserve native tree, style and event-path behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: DOM utilities preserve native tree, style and event-path behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: safe-area measurement releases the native probe after failure unlike the previous workspace implementation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "published: DOM utilities preserve native tree, style and event-path behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: DOM utilities preserve native tree, style and event-path behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: safe-area measurement releases the native probe after failure unlike the previous workspace implementation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "published: DOM utilities preserve native tree, style and event-path behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: DOM utilities preserve native tree, style and event-path behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: safe-area measurement releases the native probe after failure unlike the previous workspace implementation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "editor-types.spec.js", + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "editor-types.spec.js", + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "editor-types.spec.js", + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: player descriptor order and constructor/static surfaces match the published core", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy listener can mount a replacement without the old constructor overwriting it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: teardown during capability detection stops remaining player installers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: destroy during initial native volume assignment stops later construction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: teardown during capability detection stops remaining player installers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: destroy during initial native volume assignment stops later construction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: player descriptor order and constructor/static surfaces match the published core", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy listener can mount a replacement without the old constructor overwriting it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: teardown during capability detection stops remaining player installers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: destroy during initial native volume assignment stops later construction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: teardown during capability detection stops remaining player installers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: destroy during initial native volume assignment stops later construction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: player descriptor order and constructor/static surfaces match the published core", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy listener can mount a replacement without the old constructor overwriting it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: teardown during capability detection stops remaining player installers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: destroy during initial native volume assignment stops later construction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: teardown during capability detection stops remaining player installers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: destroy during initial native volume assignment stops later construction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: constructor callback hosts expose only initialized components", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: container validation rejects non-div elements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: constructor callback hosts expose only initialized components", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: container validation rejects non-div elements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "precise declarations: actual return values and callback receivers agree with the installed view", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: constructor callback hosts expose only initialized components", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: container validation rejects non-div elements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: constructor callback hosts expose only initialized components", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: container validation rejects non-div elements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "precise declarations: actual return values and callback receivers agree with the installed view", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: constructor callback hosts expose only initialized components", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: container validation rejects non-div elements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: constructor callback hosts expose only initialized components", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: container validation rejects non-div elements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "precise declarations: actual return values and callback receivers agree with the installed view", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "webkit", + "status": "passed", + "retry": 0 + } + ], + "reportSha256": "40ff14945535eac23006302567166314838d306854133433e657dc014c003fcf", + "logSha256": "471715463991d1125ca1a12593c31be8c56139fd661d02178c847c47a11d6dfc" + }, + { + "variant": "legacy", + "stats": { + "startTime": "2026-09-11T12:56:21.797Z", + "duration": 427435.562, + "expected": 1749, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "counts": { + "chromium": 583, + "firefox": 583, + "webkit": 583 + }, + "nativePipCapabilities": [ + { + "engine": "chromium", + "standard": true, + "webkit": false + }, + { + "engine": "firefox", + "standard": true, + "webkit": false + }, + { + "engine": "webkit", + "standard": false, + "webkit": false + }, + { + "engine": "chromium", + "enabled": true, + "request": true, + "exit": true + }, + { + "engine": "firefox", + "enabled": true, + "request": true, + "exit": true + }, + { + "engine": "webkit", + "enabled": false, + "request": false, + "exit": false + } + ], + "cases": [ + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: Shift F10 opens the default info action and closing info returns to the original control", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context menu Escape closes before fullscreen and Tab continues from its origin", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard choice navigation waits for activation and retains existing selection events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom context actions retain callbacks, typeahead and focus across replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native context content retains input editing and button activation without nested roles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: disabled context menus do not claim the keyboard opening gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: a hidden or disabled origin falls back to the player and outside focus is preserved", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: native editable context gestures remain native while pointer opening preserves external focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: keyboard menu remains inside the player and ignores a canceled opening", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: custom menu handoff to mini returns to the control that opened the menu", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-contextmenu.spec.js", + "title": "candidate: context keyboard and focus ownership stay local to each player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused control restores its new entry without intermediate focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing a focused control chooses a surviving neighbor and preserves external focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: failed control replacement recovers focus but a veto keeps the original focused entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: callbacks can transfer focus outside without an intermediate or final control focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: replacing a focused selector option transfers focus to the new control", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: focus recovery skips unavailable controls and uses a replacement native button", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: an unrelated instance update cannot take focus from another player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-controls.spec.js", + "title": "candidate: a disabled native replacement falls back and focus callbacks can destroy the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info keyboard entry, Space close and Escape preserve the opening control", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info pointer and programmatic visibility preserve unrelated focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: repeated info init replaces keyboard bindings and retains the current return target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: info with a removed origin returns to the player and destruction disables retained controls", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "published: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: optional SSR info wrapper may be absent without preventing polling and close", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-info.spec.js", + "title": "candidate: failed info name initialization releases its handlers and permits a clean retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen keyboard activation retains focus through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen external exit preserves the current in-player focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: PiP keyboard control follows real native capability without a second playback action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: SSR retains native nodes while keyboard controls toggle real subtitle cues and survive fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen keyboard activation retains focus through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen external exit preserves the current in-player focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: PiP keyboard control follows real native capability without a second playback action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: SSR retains native nodes while keyboard controls toggle real subtitle cues and survive fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen keyboard activation retains focus through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: native fullscreen external exit preserves the current in-player focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: PiP keyboard control follows real native capability without a second playback action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-integration.spec.js", + "title": "candidate: SSR retains native nodes while keyboard controls toggle real subtitle cues and survive fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: lock Tab fallback works without native inert and preserves caller focus attributes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-lock.spec.js", + "title": "candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini pointer entry preserves focus and Space closes after keyboard navigation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: programmatic mini exit preserves external focus and removed return targets use the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: destroying from mini return focus cancels late notifications and retained controls", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-mini.spec.js", + "title": "candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: selector Space commits once and Escape closes before web fullscreen exits", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: keyboard selector retains asynchronous choice ownership and disposal", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: pointer hover and selector selection retain their existing click behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: custom native controls retain their semantics and typing inside selector content", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: native trigger markup remains a single button and can open the existing popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: a dismissed hovered selector releases the next Escape to fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-selector.spec.js", + "title": "candidate: hovering an empty selector does not announce an expanded popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is hidden", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is disabled", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting navigation ignores hidden rows and inert descendants", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is hidden", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is disabled", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting navigation ignores hidden rows and inert descendants", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is hidden", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting exit falls back to the player when its button is disabled", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting navigation ignores hidden rows and inert descendants", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting keyboard enters nested panels and returns to the originating item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting switches and native ranges keep callbacks and avoid player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: setting update, failed replacement and removal recover visible focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: suspended settings ignore keyboard callbacks and restored items resume", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: native setting buttons retain their role, click path and keyboard navigation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-setting.spec.js", + "title": "candidate: destroying during moved focus restoration cancels fullscreen notifications", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress is the first control, seeks with owned keys and follows actual media time", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: volume panel opens from keyboard focus and the slider unmutes without seeking", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: unknown duration disables progress until metadata returns and labels use i18n", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility-slider.spec.js", + "title": "candidate: progress removal and volume destruction inside callbacks cancel pending writes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "published: Tab skips the non-interactive main controls", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: keyboard reaches stable play control and toggles once with focus retained", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: mute state, focus visibility and automatic hiding follow keyboard focus", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: custom control keyboard clicks retain the callback and release on replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: native buttons inside custom controls retain activation without player hotkeys", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "accessibility.spec.js", + "title": "candidate: pointer focus does not prevent the existing automatic control hiding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "published: DOM utilities preserve native tree, style and event-path behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: DOM utilities preserve native tree, style and event-path behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: safe-area measurement releases the native probe after failure unlike the previous workspace implementation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "published: DOM utilities preserve native tree, style and event-path behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: DOM utilities preserve native tree, style and event-path behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: safe-area measurement releases the native probe after failure unlike the previous workspace implementation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "published: DOM utilities preserve native tree, style and event-path behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: DOM utilities preserve native tree, style and event-path behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "dom-boundaries.spec.js", + "title": "candidate: safe-area measurement releases the native probe after failure unlike the previous workspace implementation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "editor-types.spec.js", + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "editor-types.spec.js", + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "editor-types.spec.js", + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: player descriptor order and constructor/static surfaces match the published core", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy listener can mount a replacement without the old constructor overwriting it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: teardown during capability detection stops remaining player installers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: destroy during initial native volume assignment stops later construction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: teardown during capability detection stops remaining player installers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: destroy during initial native volume assignment stops later construction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: player descriptor order and constructor/static surfaces match the published core", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy listener can mount a replacement without the old constructor overwriting it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: teardown during capability detection stops remaining player installers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: destroy during initial native volume assignment stops later construction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: teardown during capability detection stops remaining player installers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: destroy during initial native volume assignment stops later construction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy cleans the mounting template with removeHtml=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: player descriptor order and constructor/static surfaces match the published core", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: proxy-time destroy listener can mount a replacement without the old constructor overwriting it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: teardown during capability detection stops remaining player installers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "published: destroy during initial native volume assignment stops later construction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: subclasses retain receiver identity, initialization timing and static inheritance", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: omitted unused SSR nodes stay nullable without an eager template rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: teardown during capability detection stops remaining player installers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "initialization.spec.js", + "title": "candidate: destroy during initial native volume assignment stops later construction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: constructor callback hosts expose only initialized components", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: container validation rejects non-div elements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: constructor callback hosts expose only initialized components", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: container validation rejects non-div elements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "precise declarations: actual return values and callback receivers agree with the installed view", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: constructor callback hosts expose only initialized components", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: container validation rejects non-div elements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: constructor callback hosts expose only initialized components", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: container validation rejects non-div elements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "precise declarations: actual return values and callback receivers agree with the installed view", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: constructor callback hosts expose only initialized components", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "published: container validation rejects non-div elements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: constructor callback hosts expose only initialized components", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "candidate: container validation rejects non-div elements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "runtime-types.spec.js", + "title": "precise declarations: actual return values and callback receivers agree with the installed view", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "webkit", + "status": "passed", + "retry": 0 + } + ], + "reportSha256": "66b6ac7670f9f9ec46df8f0010e0a20d5af21f2b8577f2f410896cf283006c7d", + "logSha256": "7707d6967114919c568fe3eef306a595cff2a06d4a3d7ece04c601d8d73f30d4" + } + ], + "settingExitBefore": { + "stats": { + "startTime": "2026-09-11T12:45:55.263Z", + "duration": 17777.717999999997, + "expected": 0, + "skipped": 0, + "unexpected": 4, + "flaky": 0 + }, + "cases": [ + { + "title": "candidate: setting exit falls back to the player when its button is removed", + "engine": "chromium", + "status": "unexpected" + }, + { + "title": "candidate: setting exit falls back to the player when its button is hidden", + "engine": "chromium", + "status": "unexpected" + }, + { + "title": "candidate: setting exit falls back to the player when its button is disabled", + "engine": "chromium", + "status": "unexpected" + }, + { + "title": "candidate: setting navigation ignores hidden rows and inert descendants", + "engine": "chromium", + "status": "unexpected" + } + ], + "reportSha256": "15c5ec8603e7a88617d52d711d77ff18851830b8269d80c535faf81088570e6e", + "probeLogSha256": "3d4757b54a5cb61b4a1f6505521f377ee051640c8817508eee3115815ee842e9" + }, + "interruptedRun": { + "logSha256": "a1d0ebe2dbecd175ff20e15ac8c2763e95270ee1faff36492efc0d871cbf5569", + "reason": "Stopped the verified process tree after a separate real-browser probe reproduced focus in a hidden setting panel. The old installed artifact was superseded; no full pass is claimed for that interrupted run." + }, + "phaseSnapshots": { + "refactor/baselines/keyboard-buttons-partial.json": "f573ae4eb0cc2cbfcbbbed25776e727552d7486375c5af50a48a51a7f878865f", + "refactor/baselines/keyboard-contextmenu-partial.json": "fb3820a1bfed4fdaa571aeb319bc36911a3e58df47cc8b635cfdbe681bb3becf", + "refactor/baselines/keyboard-control-focus-partial.json": "c9ce7ab5fff842ea6b22d85600c70abc24e79f42cdaa5d4fb7e0d413d84f1f50", + "refactor/baselines/keyboard-info-lock-partial.json": "3bf6a112f9c8c4f28ee7605f1e8e84fb557ecd45169e02273438034de8a77ed3", + "refactor/baselines/keyboard-mini-partial.json": "7f2b1b8430248f8ab2a0e4c1e964bc0366361761521659f3a325f9a09b26df98", + "refactor/baselines/keyboard-selectors-partial.json": "bdbaddc0caba4779a4f8d3aaf3f789f85ee3701827c9cd4f700b0ffa29ba2576", + "refactor/baselines/keyboard-settings-partial.json": "bbb6631e1169cc1c0fb4dac5add058e3e8df0a8ff8b801856f80342b9e3c6fe6", + "refactor/baselines/keyboard-sliders-partial.json": "66dc2d6695371db8add287e6ec7d072162d245f94b8ffc21ff994ce45049fea1" + }, + "resolvedRisk": "BASE-DOM-01", + "limitations": [ + "Browser evidence covers installed core and chapter plus frozen published core/chapter fixtures, not all ecosystem packages.", + "Windows headless Chromium and Firefox support the standard native PiP API in this run; WebKit validates unsupported capability fallback. None certifies physical OS or Apple PiP controls.", + "Native fullscreen, real WebVTT cues, SSR node retention, focus and keyboard navigation were exercised. Screenshots and DOM checks are not screen-reader certification.", + "Physical touch/IME/Apple/AirPlay and assistive technology remain linked release-review gates; CORE-22 still performs full core stage acceptance.", + "Other packages, CI/CD completion, next-major versions and the three release reviews remain planned work. No push, tag, merge or publication." + ] +} diff --git a/refactor/changes/2026-09-11-CORE-23-keyboard-focus.md b/refactor/changes/2026-09-11-CORE-23-keyboard-focus.md new file mode 100644 index 000000000..0a50ef1c3 --- /dev/null +++ b/refactor/changes/2026-09-11-CORE-23-keyboard-focus.md @@ -0,0 +1,173 @@ +# CORE-23 键盘、焦点与可访问名称 + +从 faaa3e8c 接续,开始时工作区干净。任务 doing,覆盖主要控件、设置树/范围输入、选择列表、模式退出及字幕可用性;本页随实现补充证据,不代表全任务已完成。 + +## 已核实的问题与边界 + +BASE-DOM-01 已记录主要控件没有 Tab 入口。进一步源码审查发现:播放/音量由两个互斥显示的图标处理点击,直接让图标可聚焦会在切换时隐藏焦点;控件自动隐藏仅检查鼠标/播放/输入状态;设置按钮/树和质量 selector 依赖点击及 hover,未实现键盘操作。已有 tooltip 提供 aria-label,应复用当前语言文本。 + +保留现有 DOM 节点和类名、指针点击事件及公开回调形状。新增内部按键归属记录,避免键盘激活同时触发全局 Space 快捷键;不把所有 defaultPrevented 事件一概排除,以免改变旧自定义热键行为。内部监听器随条目/实例 scope 释放,更新/移除/销毁后不得继续响应。 + +实现依据:[WAI Button Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/button/)、[Slider Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/)、[Keyboard Interface](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/)。采用 Enter/Space 激活、可见焦点及范围键盘语义;角色和属性必须与真实交互一起验证。这些模式不等于整个产品已通过屏幕阅读器或 WCAG 认证。 + +## 分步实施与验收 + +1. 固定实际 Tab 缺口,建立可清理的按钮按键处理,接入稳定的主控件节点与已有点击路径。 +2. 补齐进度/音量范围操作、选择列表与设置树的进入/返回/关闭和焦点恢复;保护输入和已有快捷键。 +3. 检查全屏/mini 等模式退出、动态更新/移除、跨实例、SSR、名称变化及字幕可用性。 +4. 严格类型、风险用例、安装包及三浏览器完整回归;更新架构、风险、任务状态后独立提交。 + +CORE-23 已完成。按钮、滑块、选择列表、设置树、动态控件、mini、信息面板、锁定层和默认菜单均已实现并取得阶段证据;模式退出、SSR/字幕及设置入口失效的补充检查通过,新安装包现代/legacy 全量验收通过,BASE-DOM-01 已关闭。下列各阶段记录保留当时的状态与证据,最终结论见末尾验收表。 + +## 按钮与焦点第一阶段 + +新增 accessibility/button、keyboard、focus 三个 TS 模块。按键标记保留原事件身份,Enter 按下/Space 松开复用旧 click 路径,阻止重复按键、失焦或销毁后的晚到操作;旧 Hotkey 的普通 keydown 观察和无关 defaultPrevented 策略保留。原生 button/summary/ARIA button/switch 的激活键及链接 Enter 不被播放器劫持,KeyK 等其他自定义快捷键仍工作。 + +已接入主要按钮和自定义 option.click 控件。播放使用稳定 wrapper;音量保留原图标/面板层级,在互斥图标切换时只移交原有焦点;设置按钮增加 aria-expanded。原有 tooltip/i18n 提供名称,没有新增英文专用翻译键。键盘焦点更新已有 isFocus/isInput,不增加指针 focus/blur 公开事件次数。新增焦点样式和 art-keyboard-focus 类。 + +首次真实 Chromium 运行固定 Tab 缺口:发布基线通过“控件被跳过”的已知行为断言,修改前候选在目标可达断言失败。首轮三浏览器有三个 Firefox 用例失败,精确探针确认原生 video 本身先接受 Tab;修正测试保留该原生入口,再验证控制按钮,未删除或跳过失败测试。随后新增鼠标用例复现本轮最初 :focus-within/任意焦点策略会让控制栏常驻;改为独立输入方式与资源归属,保留鼠标自动隐藏。该回归及修正证据保留在阶段记录中。 + +当前 accessibility/hotkey 三浏览器共 69 项通过(含 18 项按钮/焦点/指针用例),25 项按钮/焦点/Hotkey/组件资源单元通过。最终本阶段 CI 456 项(425 单元、6 工程、25 基线)、232 个生产 TS 文件严格检查通过。[阶段证据](../baselines/keyboard-buttons-partial.json) 保存当前源/用例指纹、三组失败复现和最终通过结果。核心源已有改动,当前浏览器使用 Vite 源码构建,不能作为最新 npm/legacy 安装产物的验收;完整包构建和全量矩阵留最终任务收尾。 + +下一步继续进度/音量 slider、selector、设置树与 Escape/焦点恢复、动态更新/跨实例/SSR/字幕检查。CORE-23 和 BASE-DOM-01 仍开放,未创建任务完成 commit;上一完成任务仍为 faaa3e8c。无新依赖、版本调整、push/publish/tag/merge。 + +## 进度与音量滑块阶段 + +新增 accessibility/slider.ts 与 control/progress/keyboard.ts,分别负责通用范围键盘/ARIA 状态和播放器进度绑定。原 progress/interactions.ts 保持鼠标职责。方向键使用 SEEK_STEP 或 VOLUME_STEP;PageUp/PageDown 使用十倍步长,Home/End 到达端点,重复按键可连续调整。无有效时长/范围时禁用操作并认领按键,避免回落到播放器全局快捷键;ARIA 数值随实际媒体时间、时长、音量更新。 + +进度按键保持 setBar 在 seek 之前,第三个指针事件参数省略,不把 KeyboardEvent 混入旧 MouseEvent/TouchEvent 类型。回调切源、移除、销毁或触发更新的嵌套按键后,旧 seek 不得继续。音量键先取消静音再设置音量,muted 回调销毁或触发新操作会取消旧写入。音量范围位于原图标按钮之外,键盘聚焦静音图标时展开面板,Tab 继续进入滑块;鼠标拖动和原图标节点保留。 + +增加 Progress 可访问名称及十二个已有语言字典的翻译。public/i18n.ts 使用可选 Progress 字段,保持完整旧字典可赋值;通过 build:types/build:ts 同步生成包声明与 Monaco 声明,未手工修改生成文件。无新增依赖。 + +验证与实际修正: + +- 新增七项单元用例,与原进度拖动测试合计 17 项通过:步长/重复/上下限、无效范围、修饰键/IME、scope 清理、事件顺序、切源与嵌套取消。 +- 初次 Chromium 浏览器 9 通过、1 失败,复现 transition: all 将新 visibility 状态一起过渡,快速 Tab 跳过音量滑块。限制过渡为 opacity/transform 后,原用例通过,未通过等待或跳过来隐藏该问题。 +- 首次三浏览器 122 通过、1 失败,WebKit 在请求 1 秒时实际落点约 1.003 秒;测试改为验证实际时间的步长和 ARIA 同步,并保留请求值/事件顺序的精确检查。 +- 首次完整 CI 检出 Monaco 声明遗漏新翻译键;build:ts 生成修复后完整 CI 463 项通过(432 单元、6 工程、25 基线),234 个生产 TS 文件严格检查通过。此处计数包括核心与 chapter。 +- 最终 accessibility、hotkey、progress-quality 三浏览器 123 项全部通过,无失败、重试或跳过;其中滑块专项 12 项。实际版本 Chromium 153.0.8010.12、Firefox 155.0、WebKit 26.6。 + +[滑块阶段证据](../baselines/keyboard-sliders-partial.json) 保存源文件、声明、用例、日志及报告指纹、浏览器构建来源、失败复现与最终结果。此前按钮阶段快照保持原样。本阶段浏览器仍为 Vite 源码构建,最新安装包/legacy 全量验收尚未执行。 + +下一步处理 selector 与设置树的键盘进入、选择、返回/Escape,以及动态焦点恢复、模式退出、跨实例/SSR/字幕检查。CORE-23 仍 doing,BASE-DOM-01 保持开放,总体 57 done、1 doing、156 todo;完成整个任务后再独立 commit。 + +## 选择列表阶段 + +control/selector-keyboard.ts 独立管理打开/关闭、焦点与键盘导航,旧 selector.ts 继续负责条目绑定、check 和异步 onSelect 结果归属。Tab 可到达当前值,Enter/Space/上下键打开并聚焦当前项;方向键、Home/End 和连续字符前缀仅移动焦点,不提前切换清晰度。Enter/Space 通过原 item.click 提交,保持回调 this、item/node 身份、click 参数及已有 generation/trackSelection 检查。Escape 关闭并返回当前值,Tab 离开不提交;关闭后再次 Escape 交回播放器。 + +普通列表采用 listbox/option 和 aria-selected,参考 [WAI Listbox Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/)。含原生交互 HTML 的选项采用 group,保留按钮/输入框语义与编辑按键;group 不声明不匹配的 aria-haspopup。原生按钮作为当前值时直接承担展开入口,外层不新增嵌套 button 角色。check/异步 HTML 返回会刷新该绑定,仅在替换已聚焦的当前值子节点导致焦点回到 body 时恢复新入口;回调主动移交外部焦点时不抢回。调用方自定义交互内容仍需自行提供其可访问名称。 + +列表的可见性过渡只涉及 opacity/transform,避免重现滑块阶段的快速 Tab 问题。hover 与键盘打开状态分别维护,Escape 可在鼠标仍悬停时关闭列表。disabled 空列表不会报告 expanded=true。原来的 DOM 类名、selector getter 描述符、鼠标 click 路径和异步失效检查保留;无新增依赖或公开类型字段。 + +新增十项浏览器场景,覆盖实际 Tab/Enter/Space、typeahead、Escape 与 web fullscreen 的先后归属、空列表、鼠标 hover、异步竞态/移除、回调移交焦点及原生按钮/输入框。截图检查确认当前项高亮与独立焦点框同时可见。补充用例先在 Chromium 复现“关闭后的第二次 Escape 仍被吞掉”和“空列表悬停报告展开”两个失败,再统一用实际 expanded 条件修复;失败与最终验证均保留在阶段证据中。 + +最终 CI 463 项通过(432 单元、6 工程、25 基线),235 个生产 TS 文件严格检查通过;accessibility/hotkey/progress-quality/components 匹配到的三浏览器回归共 282 项通过(包括 prompt-components),无失败、重试或跳过,其中选择列表专项 30 项。[选择列表阶段证据](../baselines/keyboard-selectors-partial.json) 保存当前源文件/用例、完整 CI、浏览器构建来源、三引擎截图指纹和修复前两个失败。浏览器仍使用 Vite 源码构建,尚非新安装包/legacy 全量验收。 + +下一步是设置树、模式退出、动态控件移除/替换焦点恢复,以及跨实例/SSR/字幕检查。任务与发布门槛保持开放:CORE-23 doing,BASE-DOM-01 open;57 done、1 doing、156 todo,完成全部任务验收后再独立 commit。无 push/publish/tag/merge。 + +## 设置面板、DOM 移动焦点与原生跳转校正阶段 + +设置模块新增 keyboard.ts、keyboard-item.ts、keyboard-focus.ts,分别负责面板导航和关闭、条目按键/语义、可见焦点目标及恢复。设置按钮 Enter/Space/ArrowDown 进入当前项,ArrowUp 直接进入最后一项;方向键/Home/End 在可操作项间移动,Right 进入子面板,Left/返回行回到原项,Escape 关闭并返回设置按钮。Tab 离开后关闭,不把原生 input 的编辑键交给播放器。原生按钮保留浏览器 click 路径,不新增嵌套按钮角色;开关同步 aria-checked,选择项同步 aria-current,范围输入使用条目文字作为名称。 + +面板与条目监听器遵循已有 scope 暂停/恢复/释放。更新成功、失败回滚及移除后,仅在原焦点因替换或隐藏丢失时恢复可见目标;回调已移交外部焦点则保留外部焦点。focusout 使用可释放的零延迟任务读取浏览器完成 Tab 后的实际焦点:首次微任务版本会在焦点暂处 body 时误关闭,已由真实用例复现修正。暂停中的条目既不能激活,也不能让方向键落入全局 seek。 + +accessibility/moved-focus.ts 保存 DOM 移动前实际聚焦节点。网页全屏进入/退出和失败恢复后,只有该节点仍连接且移动导致焦点落到 body 才恢复;销毁清理不聚焦,恢复时回调销毁会阻止后续 fullscreenWeb/resize 通知。真实用例先复现 FULLSCREEN_WEB_IN_BODY 丢失设置按钮焦点,再验证恢复和销毁边界。新增 Back、Settings 的十二语言翻译,公开字段可选,包和 Monaco 声明均用生成脚本同步。无新增依赖。 + +扩大回归时复现 WebKit 的原生跳转竞态:End 后立即 PageDown 已正确发出 seek(3),焦点未丢失,但结束事件随后将实际时间写回约 8 秒。重复五次探针中四次失败,不能归为帧级舍入。进度键盘复用 source/restore-position.ts 的一次有限校正;初次仍经过原 seek setter,校正使用 currentTime,不重复公开 seek 事件。操作 scope 同时归控件与 source 管理;新键盘操作、公开 currentTime 写入、切源、移除或销毁会取消旧校正。新增单元检查一次上限、事件顺序、手动覆盖及监听器释放;修正后五次 WebKit 探针全部通过。 + +验证记录: + +- 完整 CI 468 项(437 单元、6 工程、25 基线)和 239 个生产 TS 严格检查通过。严格检查期间修正 cleanup 的 undefined 返回约定和 proxy 媒体宿主的内部结构类型,没有放宽到 any。 +- 扩大 accessibility/setting/display-web/hotkey/progress-quality/source 三浏览器回归 477 项通过。该运行在上述内部类型修正前启动;之后对最终源码重跑设置、滑块、切源专项 57 项,全部通过。分别保存构建指纹,不能把两次当作同一构建的全量通过。 +- 最终专项中途出现 56 通过、1 失败:旧测试 once(setBar) 会被媒体加载的 loaded/零进度更新提前消费,控件提前移除后按键实际走全局 Hotkey。测试改为匹配本次非零 played 更新后再移除,仍精确验证取消 seek;未添加等待、重试或跳过。修改后的两个浏览器文件额外 lint 通过。 +- 七项设置场景跨三引擎共 21 项通过,覆盖真实 Enter/Space/Tab、树导航、switch/range、更新回滚、暂停和原生按钮。截图目标改为全屏移动后的实际 .art-video-player,避免只截到旧容器的局部视频。 + +[设置阶段证据](../baselines/keyboard-settings-partial.json) 保存失败报告、源文件/类型/测试指纹、CI、两轮浏览器构建及截图。此前三个阶段快照不改写。当前均为 Vite 源码构建;新安装包/legacy 全量验收、剩余动态控件焦点/模式退出/跨实例/SSR/字幕检查及最终提交仍未完成。CORE-23 doing,57 done、1 doing、156 todo;无版本调整、push/publish/tag/merge。 + +## 动态控件替换与移除焦点阶段 + +修改前在真实 Chromium 固定六个场景,其中五项失败:聚焦控件更新、移除、失败替换、聚焦 selector 子项替换及最后控件移除均会失去焦点;回调主动聚焦外部的既有场景通过。新增 component/focus.ts,Component.remove/update 在 finally 中结束焦点操作,仅对 control 生效;同一 update 的内部 remove 不先把焦点移到相邻项,保持单次最终恢复和旧 add/update 返回约定。 + +优先聚焦同名替换条目的可用节点,否则按原 DOM 顺序选择后续或前一个仍存活的控件。原生按钮作为实际目标,隐藏/禁用字段集/aria-disabled/inert 内容不能承担恢复目标。beforeUnmount 拒绝移除时原节点仍聚焦;mounted 失败清理后恢复相邻控件。回调主动聚焦外部,或正在操作其他实例时不移交焦点;焦点恢复中的回调销毁播放器后,保留节点也不得再触发旧 click。 + +没有可用控件时使用 accessibility/player-focus.ts 聚焦仍连接的播放器。首版立即移除临时 tabindex 的实测会让 Chromium 再次失焦;现在保留自建 tabindex=-1 至实例清理,不增加顺序 Tab 停留点,既有调用方 tabindex 保留。该失败及修正记录保存在独立报告中。 + +最终增加到九项动态控件场景,包括原生替换按钮、禁用字段集、跨实例隔离及恢复时销毁,三引擎共 27 项通过。完整 CI 468 项通过(437 单元、6 工程、25 基线),241 个生产 TS 文件严格检查;accessibility/components/setting/hotkey/progress-quality 组合三浏览器 507 项通过,无失败、重试或跳过。12 项原组件资源和焦点单元专项也通过,未添加只镜像实现的模拟 DOM 测试。 + +[动态控件阶段证据](../baselines/keyboard-control-focus-partial.json) 保存两组先失败的报告、最终源/用例指纹、CI 和完整组合回归。架构说明同步至 packages/artplayer/ARCHITECTURE.md;此前阶段快照不改写。本阶段无新增依赖、公开类型或版本调整。 + +源码检查显示 mini-view.ts 的关闭与播放图标、info/poll.ts 的关闭图标及 plugins/lock.ts 的层按钮仍主要依赖点击,后续需先固定真实键盘缺口,再补模式内操作和退出焦点。跨实例动态控件已验证,但不能代表整个播放器的跨实例可用性已验收。SSR/字幕及安装包/legacy 全量检查继续保留;CORE-23 doing、BASE-DOM-01 open,57 done、1 doing、156 todo,无任务完成 commit,无 push/publish/tag/merge。 + +## mini 播放器键盘与退出焦点阶段 + +修改前四项真实 Chromium 场景全部失败。自建 mini-view 的既有关闭节点和稳定播放 wrapper 现使用 keyboardButton,Enter/Space 通过原关闭或当前可见播放/暂停图标的 click 路径执行。播放状态变化保留 wrapper 焦点并更新名称;弹窗内 Escape 仅在 mini 活跃时认领。focus-within 显示原 hover 按钮,focus-visible 提供白色焦点框。使用 Close、Mini Player、Play、Pause 既有翻译键,无新增公开类型或字典字段。 + +新增 display/mini-focus.ts 管理会话来源:键盘从播放器进入时聚焦关闭按钮;指针/程序打开不会抢走外部焦点。关闭仅在焦点仍属于弹窗时恢复原入口,入口已删除、隐藏、禁用或 inert 时聚焦播放器;新会话清除陈旧来源。mini 原有 revision/closing 检查围绕焦点回调,恢复焦点时销毁或再次切换会取消旧 mini 通知。销毁清理不尝试恢复焦点。 + +保留首次/复用 DOM 顺序、拖动、播放器视频节点移动/恢复和失败重试。调用方提供的自有 mini 容器不追加本轮自建按钮绑定、角色或样式,其交互继续由调用方管理;退出 API 可恢复其当前弹窗焦点。新 UI 资源随已有 mini scope 释放。 + +最终六场景跨三引擎共 18 项通过,覆盖实际 Tab/Enter/Space/Escape、真实播放/暂停、指针打开、重复会话、外部/隐藏/删除来源、国际化、隐藏后的晚到按键,以及焦点回调销毁后的节点点击。此前 Chromium 组合 24 项通过;最终 accessibility/display-mini/display-web/hotkey 三浏览器组合 300 项全部通过,无失败、重试或跳过。完整 CI 468 项、242 个生产 TS 严格检查通过。 + +[mini 阶段证据](../baselines/keyboard-mini-partial.json) 保存修改前失败、最终源和测试指纹、CI、三引擎版本及构建来源;截图保存在本地缓存并检查焦点框和按钮可见性。包内架构文档已同步。当前仍为 Vite 源码构建;信息面板/锁定层、其他模式退出、跨实例/SSR/字幕和安装包/legacy 最终验收仍待完成。CORE-23 doing,57 done、1 doing、156 todo,无新依赖、版本调整、任务完成 commit 或 push/publish/tag/merge。 + +## 信息面板与锁定层阶段 + +信息面板新增 info/keyboard.ts,监听器随原 poll scope 初始化、替换和释放,保留 Info 自有字段、原型方法、轮询次数及 close click 路径。键盘打开聚焦关闭按钮,Enter/Space/Escape 关闭并返回当前会话的播放器入口,原入口不再可用时聚焦播放器。程序/指针操作保留外部焦点;重复 init 不丢失返回目标。名称复用 Close、Video Info。失败名称初始化释放新监听器和轮询,原错误仍可捕获并重试。 + +严格类型检查发现 $info 在历史模板边界中可空,不能为了通过检查直接断言为必需。保留这个 SSR 约定:缺少外层时跳过依赖该节点的键盘逻辑,轮询和原关闭事件保持;旧发布版和候选版都通过真实 SSR 节点保留与关闭用例。节点存在时才加 group 名称和按键行为。Node 单元宿主补齐实际新增的 EventTarget/属性契约,原轮询和错误用例仍完整执行。 + +锁定层新增 plugins/lock-keyboard.ts,使用原层节点作为稳定 toggle button,aria-pressed 跟随 lock 通知,Enter/Space 复用原 click,Escape 仅在锁定状态解锁。accessibility/suspend-focus.ts 在锁定期间为控制栏设置自有 inert/aria-hidden 并保存 tabindex,MutationObserver 处理新增与移出节点;解锁、移除或销毁恢复自有值,已被调用方改成不同值的属性不覆盖。实际移除原生 inert 后仍能通过 Tab 回退用例,原有 inert/aria-hidden 和正 tabindex 也能恢复。 + +键盘焦点样式不再覆盖锁定控制栏原来的隐藏位移;锁定按钮在控制栏隐藏时保留 Tab 可达性,仍按原逻辑视觉隐藏,聚焦后显示。新增可选 Lock 字典类型和十二语言翻译,通过 build:types/build:ts 生成包及 Monaco 声明,旧完整字典不被新增必需字段拒绝。无新依赖。 + +另外固定了已锁定状态重挂载层的旧缺陷:原 mounted 总把锁定图标隐藏,与实际 state 不符;现在按 getState 初始化图标,保留通常未锁定初始化的样式写入。重挂载恢复新的焦点 scope,Space 解锁仍仅发一次事件。 + +验证与纠正: + +- 信息面板修改前四项 Chromium 场景中三项失败、程序/指针焦点场景通过;锁定层修改前三项全部失败。实现后首批信息面板/提示组件 Chromium 19 项和相关 Node 17 项通过。 +- 首轮锁定组合有一项测试错误假设外部 Outside 按钮紧随播放器,真实测试页先有 Play/Pause;依据实际 Tab 结果改为验证 Play,再 Shift+Tab 返回锁定按钮。未增加等待或跳过。 +- 重挂载先复现图标 display:none,修正后浏览器把 flex 子项的 inline-flex 计算为 flex,导致三个引擎的计算样式断言失败。测试改为实际可见性与 inline display 值分别检查,仍保留解锁次数及属性清理断言。失败和修正报告都保留。 +- 最终完整 CI 468 项通过(437 单元、6 工程、25 基线),245 个生产 TS 文件严格检查;最后仅上述浏览器样式断言调整,额外 lint 通过。最终 accessibility/builtin-layers/prompt-components/hotkey 三浏览器组合 306 项全部通过,无失败、重试或跳过;信息面板共 21 项(含旧/新 SSR 对照),锁定层共 18 项。新专项没有未处理浏览器错误或 console error。 + +[信息面板与锁定层证据](../baselines/keyboard-info-lock-partial.json) 固定源文件、单元宿主、公开/编辑器声明、用例、CI、构建指纹及各次失败。移动条件使用 UA 选择加真实键盘测试,不能当作物理 Android/iOS 或屏幕阅读器验收。默认菜单入口、其他模式退出、跨实例/SSR/字幕和新安装包/legacy 完整矩阵继续交本任务剩余工作。CORE-23 doing、BASE-DOM-01 open,57 done、1 doing、156 todo,无任务完成 commit、版本调整或 push/publish/tag/merge。 + +## 默认菜单键盘与跨面板焦点阶段 + +修改前六项 Chromium 场景中四项失败。新增 contextmenu/keyboard.ts 管理 Shift+F10/ContextMenu、方向键/Home/End、文字导航、Escape/Tab 退出与焦点恢复;contextmenu/position.ts 原样提取鼠标定位计算,键盘使用当前元素边界作为入口坐标。容器用具名 group,动作项为 button,选择行保留 data-value span 并逐个增加按钮语义、aria-pressed;contextmenu/choices.ts 同步既有 art-current 状态。版本原生链接、自定义 button/input 保持原生角色与编辑/激活路径。 + +菜单 init 在成功添加条目后替换根 scope,重复添加失败不拆掉既有监听器。Component 焦点恢复从 control 扩展到 contextmenu,同名替换优先,否则选择 DOM 后续/前一个可用项。菜单关闭跳过已隐藏、删除、禁用或 inert 的原入口,必要时回到播放器;外部主动焦点、销毁中回调和双播放器相互独立。 + +accessibility/overlay-focus.ts 记录菜单来源,Info/mini 进入时解析到原始控件,避免退出后聚焦已经隐藏的菜单项。没有提前移动焦点或调整原 click/public 事件顺序;自定义菜单 callback 仍自行决定是否关闭,参数与 this 保持不变。输入/textarea/select/contenteditable 上的上下文菜单手势改为不拦截,这是修复用户编辑功能的行为差异(API-08),合成事件验证不等于操作过系统原生菜单。 + +Context Menu 是新增可选公开 i18n 键,十二语言及生成包/Monaco 声明一致。无依赖或版本调整。测试修正保留证据:首轮错误预期移除 Beta 后回到 Alpha,实际排序下下一项是 Info,截图确认恢复正确,现先断言 DOM 邻居再断言焦点;第二轮取消监听器错误假设 Emitter 默认 this 是 art,改为闭包引用已有实例,未修改 Emitter 契约。 + +最终完整 CI 468 项通过(437 单元、6 工程、25 基线),249 个生产 TS 文件严格检查;之后只有浏览器文件增加边界及修正上述假设,额外 lint 通过。最终 accessibility/components/prompt-components/display-mini/hotkey 三浏览器组合 444 项全部通过,无失败、重试或跳过;菜单十三场景共 39 项,无未处理错误或 console error。测试包含 Info/mini 交接、重复 init、失效来源、外部焦点/销毁、原生内容、取消打开、双实例及菜单边界,保留各引擎中文键盘焦点截图。 + +[菜单阶段证据](../baselines/keyboard-contextmenu-partial.json) 固定当前源/声明/用例、构建、CI、截图与失败报告,不改写此前快照。剩余原生模式退出、SSR/字幕和最终新安装包/legacy 全量验收继续推进;CORE-23 doing、BASE-DOM-01 open,57 done、1 doing、156 todo,尚无任务完成 commit,无 push/publish/tag/merge。 + +## 模式、SSR/字幕与最终边界审查 + +新增 accessibility-integration 四项真实场景,三引擎 12 项通过:Enter/Space 原生全屏进入退出、浏览器 API 主动退出后保留当前控件焦点、原生 PiP 键盘切换或不支持时提示,以及 SSR 保留播放器/video/字幕节点、实际 WebVTT cue、键盘字幕开关和网页全屏焦点。Chromium 153 与 Firefox 155 本次具有标准 PiP API,实际进入/退出并验证原事件;Windows WebKit 26.6 无该能力,验证既有不支持提示且不误触发播放,不能把该分支当作成功 PiP 会话。字幕维持被动呈现,不追加 Tab 停留点或强制 aria-live 逐条播报;截图检查字幕与焦点框实际可见,物理辅助技术仍由发布复盘验证。 + +第一次新安装包全量运行期间,额外真实 Chromium 探针复现设置按钮被删除后 Escape 仍聚焦隐藏面板中的条目。增加四项回归,在旧安装包上全部失败:入口删除、visibility:hidden、aria-disabled,以及导航遇到隐藏行/inert 子树。setting/keyboard-focus.ts 统一可用目标过滤,增加只接管关闭面板内焦点的设置入口恢复;无可用入口时使用播放器 fallback,外部焦点或销毁状态不接管。没有改变公开 Setting 的属性/方法或回调形状。 + +已验证原全量进程树身份后主动停止旧产物测试;保留 interrupted 日志,不计入通过。修正后三浏览器设置/集成组合 45 项通过;随后将隐藏面板断言的错误单数选择器改为实际 .art-settings,先检查唯一节点再检查隐藏,核心焦点缺陷的前后证据仍来自明确 toBeFocused 断言。最终 CI 和新打包检查重新执行,源与声明不复用旧结果。refactor/.cache/core23-setting-exit-before.json 保存四项旧产物失败;原阶段快照保留不变。 + +## 最终验收与交接 + +| 验收项 | 实际证据 | +| --- | --- | +| 结构 | 按键认领/按钮/范围/焦点与 DOM 所有权分离;控件、设置、菜单、mini、信息/锁定层各自持有局部状态和清理范围;包内 ARCHITECTURE.md 提供文件地图、回归入口及限制 | +| 类型 | 最终 CI 468 项通过,249 个生产 TS 文件严格检查;37 个公共声明无漂移;五组历史消费与八组精确消费模式无诊断,新增五个翻译字段均可选 | +| 兼容 | 保留旧构造器、属性、快捷键、click 回调参数/this、DOM/CSS 钩子及分发入口;新增键盘路径不重复激活播放;34 项隔离安装运行时契约通过,原有新旧核心/chapter 组合在全量矩阵中继续通过 | +| 真实交互 | 控件 Tab、Enter/Space、slider、selector/设置树、菜单/模式退出、动态更新移除、失效入口、双实例、SSR/字幕有真实浏览器用例,缺陷先固定失败再修正 | +| 最终安装包 | run-4QYvJQ 经 Yarn pack、隔离安装和 frozen 重装;源/声明/资源 381 文件与快照一致,工作区构建的分发内容与安装包字节一致;没有把工作区链接当作 npm 安装 | +| 完整浏览器 | modern 1749 项、legacy 1749 项;每种格式 Chromium/Firefox/WebKit 各 583 项,无失败、重试或跳过;每个用例核对已安装核心和 chapter 产物哈希 | +| 分发与导入 | 按正式脚本重建核心三个 JS 格式与 i18n;ESM/i18n/SSR 三项导入检查通过,声明/Monaco 由生成器维护 | +| 交接与提交 | 任务状态、风险台账、阶段快照和最终证据一并更新;本任务独立本地 commit,后续任务必须在核实该提交后开始 | + +[最终证据](../baselines/keyboard-validation.json) 保存源/测试/工具指纹、包完整文件清单、运行时与类型结果、两个完整浏览器矩阵、构建/安装日志指纹、设置入口四项失败及中断旧产物运行的原因。此前八份阶段 JSON 不改写。新增 Progress/Back/Settings/Lock/Context Menu 可选翻译键,十二语言与两份声明同步;本任务没有新增依赖或改版本。 + +BASE-DOM-01 resolved,只关闭主要控件 Tab 不可达这一已复现问题。Windows 浏览器与受控 adapter 检查不代表物理 Apple/AirPlay/触摸/IME 或屏幕阅读器认证;相关 REL-03/REVIEW-02 与 BASE-ENV-01 门槛保留。CORE-22 仍待核心资源/性能及生态集成总验收,其前置 ENG-08 尚未完成,因此下一项先补覆盖率、资源清理与性能报告,再进入 CORE-22。多数生态包、CI/CD、各包下一大版本和三轮发布复盘仍待推进,没有公开发布结论。 + +总体为 214 项:58 done、156 todo。回退时以父提交 faaa3e8c 为基准整体 revert 本任务 commit,同步回退源、生成声明/编辑器、dist/docs 编译文件与测试,不只回退 helper 或复制旧 bundle。无 push/publish/tag/merge。 diff --git a/refactor/plan.md b/refactor/plan.md index 779c54411..4b4ec96fb 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -4,7 +4,7 @@ 基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。 -状态:todo 157 / doing 0 / blocked 0 / done 57 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 +状态:todo 156 / doing 0 / blocked 0 / done 58 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。 @@ -125,7 +125,7 @@ | CORE-19 | artplayer
整理进度、质量、缩略图和截图 | CORE-10, CORE-13, CORE-16 | 相关 player/control 功能与纯计算分离 | 截图跨域失败、缩略图布局、quality/进度边界保持 | M | done | | CORE-20 | artplayer
收敛核心入口与依赖方向 | CORE-14, CORE-15, CORE-18, CORE-19 | Artplayer 门面、初始化依赖与最终目录 | 所有核心自有源码迁移,公开描述符/静态接口/事件差分通过 | H | done | | CORE-21 | artplayer
生成核心声明并校验包内容 | CORE-20, ENG-07 | 由 TS 生成的既有入口声明与三种发布产物 | 内部类型不泄漏,旧 JS/TS 消费者与 i18n 通过;逐项完成 CORE-07 留下的 BASE-TYPE-04/05/07 声明方案,旧合法消费者与实际返回分别留证;不能以虚假的交叉返回类型或改变运行时来掩盖冲突,未决项阻止核心声明出口;处理 CORE-10 / BASE-TYPE-08 的 setter-only 属性虚构 getter 声明,并复核 PlaybackControls 精确视图与旧 toggle 声明共存策略 | H | done | -| CORE-23 | artplayer
检查并补齐键盘、焦点与可访问名称 | CORE-13, CORE-14, CORE-17, ENG-05, BASE-04 | 主要控件/设置/模式退出的键盘与焦点回归、名称和字幕可用性检查及必要兼容修正 | 保持旧快捷键和 DOM/CSS 钩子;真实浏览器验证,不以静态属性检查代替交互;处理 BASE-DOM-01 的主要控件 Tab 不可达,保留既有名称与快捷键 | H | todo | +| CORE-23 | artplayer
检查并补齐键盘、焦点与可访问名称 | CORE-13, CORE-14, CORE-17, ENG-05, BASE-04 | 主要控件/设置/模式退出的键盘与焦点回归、名称和字幕可用性检查及必要兼容修正 | 保持旧快捷键和 DOM/CSS 钩子;真实浏览器验证,不以静态属性检查代替交互;处理 BASE-DOM-01 的主要控件 Tab 不可达,保留既有名称与快捷键 | H | done | | CORE-22 | artplayer
核心阶段完整验收 | CORE-21, CORE-23, PILOT-01, ENG-08, ENG-10 | 核心与旧插件的可自动化完整回归、资源/性能及明确外部验证缺口 | 核心自动化和公开差异处置通过;真实环境缺口链接包集成/REL 门槛,阶段完成不代表可公开发布 | H | todo | ## 5 包迁移:artplayer-plugin-chapter @@ -456,6 +456,7 @@ - CORE-19: [记录](changes/2026-09-11-CORE-19-capture-thumbnails.md) [记录](baselines/capture-progress-validation.json) - CORE-20: [记录](changes/2026-09-11-CORE-20-entry.md) [记录](baselines/entry-validation.json) - CORE-21: [记录](changes/2026-09-11-CORE-21-public-declarations.md) [记录](baselines/core-declarations-validation.json) [记录](core-public-types.md) [记录](typechecking.md) +- CORE-23: [记录](changes/2026-09-11-CORE-23-keyboard-focus.md) [记录](baselines/keyboard-validation.json) - PKG-CHAPTER-01: [记录](changes/2026-09-10-PKG-CHAPTER-01-contract.md) [记录](baselines/chapter-contract.md) - PKG-CHAPTER-02: [记录](changes/2026-09-10-PKG-CHAPTER-02-tests.md) [记录](baselines/chapter-validation.json) - PKG-CHAPTER-03: [记录](changes/2026-09-10-PKG-CHAPTER-03-typescript-modules.md) [记录](baselines/chapter-migration-validation.json) diff --git a/refactor/progress.md b/refactor/progress.md index e318059a4..9114d800e 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,79 @@ # 进度与证据 +## 最新完成:CORE-23 键盘、焦点与可访问名称 + +默认菜单、原生模式/SSR/字幕检查已完成阶段验证;最终审查另复现并修正设置入口被删除/隐藏/禁用后留下隐藏焦点,以及导航进入隐藏/inert 设置项。四项旧产物回归全部失败,修正后三浏览器设置/集成组合 45 项通过。 + +修正后的完整 CI 468 项、249 个生产 TS 文件、新安装包 34 项运行时/5 组旧类型/8 组精确类型通过;381 个源/声明/资源文件与打包快照一致,工作区生成产物与安装包字节一致。现代版与 legacy 安装包全量各 1749 项通过(各引擎 583 项),无失败、重试或跳过。见 [最终验收证据](baselines/keyboard-validation.json) 与 [实施记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。 + +CORE-23 done、BASE-DOM-01 resolved;58 done、156 todo。本任务以独立本地 commit 交付,包含源码、测试、生成文件、架构与迁移记录。下一步先完成 CORE-22 尚缺的依赖 ENG-08(覆盖率、资源与性能报告),再做核心总验收。其余生态包、CI/CD 完整流程、各包下一大版本及三轮发布复盘继续推进;没有 push/publish/tag/merge。下方各阶段保留当时的状态与证据。 + +## 当前实施:CORE-23 默认菜单键盘阶段 + +默认菜单新增 Shift+F10/ContextMenu 入口、方向键/Home/End/文字导航和 Escape/Tab 退出。保留原 action/choice 点击路径、回调参数与关闭职责;菜单转入信息面板或 mini 后回到最初控件。动态菜单项替换/移除复用组件焦点恢复;输入字段的上下文菜单手势不再被播放器拦截。Context Menu 可选翻译键、十二语言与两份声明已同步。 + +完整 CI 468 项、249 个生产 TS 严格检查通过;accessibility/components/prompt-components/display-mini/hotkey 三浏览器组合 444 项全部通过,其中菜单十三场景共 39 项,无失败、重试或跳过。见 [菜单阶段证据](baselines/keyboard-contextmenu-partial.json) 和 [实施记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。中途两个测试假设错误按实际 DOM 顺序和 Emitter 上下文契约修正,保留失败报告。 + +CORE-23 doing、BASE-DOM-01 open;57 done、1 doing、156 todo。继续原生模式退出焦点与 SSR/字幕可用性,再进行新安装包/legacy 完整验收。本阶段仍是源码构建证据,尚无本任务完成 commit,无 push/publish/tag/merge。 + +## 当前实施:CORE-23 信息面板与锁定层阶段 + +信息面板新增独立键盘模块,支持进入、关闭和返回焦点,重复 init 保留返回目标并替换监听器;缺少可选 SSR 外层时保留原轮询/关闭行为。锁定层增加稳定按钮、aria-pressed 和 Escape 解锁,隐藏控制栏暂时退出 Tab 顺序,动态新增/移出控件和清理恢复原属性;保留调用方后续修改的值。已锁定时重挂载的图标初始化也按实际状态修正。 + +最终完整 CI 468 项、245 个生产 TS 严格检查通过;accessibility/builtin-layers/prompt-components/hotkey 三浏览器组合 306 项通过,其中信息面板及锁定层共 39 项,无失败、重试或跳过。见 [阶段证据](baselines/keyboard-info-lock-partial.json) 与 [实施记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。本轮新增可选 Lock 翻译键,十二语言、包声明与 Monaco 声明已同步生成。 + +CORE-23 仍 doing、BASE-DOM-01 open;57 done、1 doing、156 todo。接下来审查默认菜单入口、其余模式退出和跨实例/SSR/字幕可用性,再做新安装包与 legacy 全量验收。当前为源码构建阶段证据,尚无本任务完成 commit;未推送或发布。 + +## 当前实施:CORE-23 mini 键盘与退出焦点阶段 + +mini 关闭和稳定播放 wrapper 已支持 Enter/Space,弹窗内 Escape 关闭;键盘打开聚焦关闭入口,关闭后恢复原控件或播放器,鼠标/程序打开保留外部焦点。重复会话不沿用陈旧入口,回调销毁/重入取消后续通知。复用现有翻译键及图标 click 路径,调用方自有 mini 容器的 DOM、样式和控件仍由调用方管理。 + +修改前四项 Chromium 场景全部失败;最终六场景跨三引擎 18 项通过。完整 CI 468 项、242 个生产 TS 严格检查通过;accessibility/display-mini/display-web/hotkey 三浏览器组合回归 300 项通过,无失败、重试或跳过。见 [mini 阶段证据](baselines/keyboard-mini-partial.json) 与 [实施记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。 + +下一步信息面板/锁定层、其他模式退出和跨实例/SSR/字幕检查,然后重新构建安装包与 legacy 全量验收。CORE-23 doing、BASE-DOM-01 open;57 done、1 doing、156 todo。当前为源码构建专项证据,尚无本任务完成 commit,未推送或发布。 + +## 当前实施:CORE-23 动态控件焦点阶段 + +新增 component/focus.ts,控件更新只在完整替换结束后恢复一次焦点;移除、禁用替换或 mounted 失败时选择可用相邻控件,beforeUnmount 中断则保留原节点。支持 selector 子项与原生按钮,跳过隐藏/禁用/inert 内容;不抢回调用方已移交外部或另一实例的焦点。最后一个控件移除后使用受实例清理管理的 tabindex=-1 聚焦播放器,不新增顺序 Tab 入口。 + +真实 Chromium 修改前六项中五项失败,修正后动态控件九场景跨三引擎 27 项通过。完整 CI 468 项、241 个生产 TS 严格检查通过;accessibility/components/setting/hotkey/progress-quality 三浏览器组合回归 507 项全部通过,无失败、重试或跳过。见 [阶段证据](baselines/keyboard-control-focus-partial.json) 与 [实施记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。 + +下一步补齐 mini/信息面板/锁定层等模式操作与退出焦点,继续跨实例/SSR/字幕可用性及最终安装包/legacy 全量验收。当前仍为 Vite 源码构建证据;CORE-23 doing、BASE-DOM-01 open,57 done、1 doing、156 todo,完成整项后独立 commit。最近完成提交仍 faaa3e8c,未推送或发布。 + +## 当前实施:CORE-23 设置面板与播放位置校正阶段 + +核心自有源码 TS 迁移已在 CORE-20 完成,公开声明生成与兼容入口在 CORE-21 完成。当前继续修改源码:设置面板新增独立键盘、条目语义与焦点恢复模块,支持进入/返回、Escape、原生范围输入及更新失败恢复;网页全屏移动播放器节点后恢复已有焦点。最新完成提交仍为 faaa3e8c,CORE-23 尚未验收提交。 + +本阶段完整 CI 468 项通过(437 单元、6 工程、25 基线),239 个生产 TS 文件严格检查通过。扩大三浏览器回归 477 项通过;随后修正内部类型和清理回调返回类型,最终源码上的设置/滑块/切源专项 57 项通过。两轮构建指纹分别保留,不能合并宣称最终源码已跑完完整矩阵。见 [设置阶段证据](baselines/keyboard-settings-partial.json) 与 [实施记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。 + +回归复现 WebKit 在 End 后立即 PageDown 时原生结束状态覆盖新 seek;复用一次有限校正,保留公开事件顺序,新操作、公开时间写入、切源、控件移除或销毁取消旧校正。修复后的 WebKit 五次重复探针通过。另修正测试 once(setBar) 提前消费加载事件的竞态,未增加等待或跳过失败。 + +总体仍为 214 项:57 done、1 doing、156 todo,覆盖 22 个包。下一步完成动态控件焦点、剩余模式退出及跨实例/SSR/字幕可用性,进行 CORE-23 新安装包和 legacy 全量验收,再提交并进入 CORE-22 核心总验收。多数生态包、后续 CI/CD、各包下一大版本、三轮发布复盘和真机门槛仍待实施。BASE-DOM-01 open;没有 push/publish/tag/merge。 + +## 当前实施:CORE-23 选择列表阶段 + +选择列表已拆出 selector-keyboard.ts,支持实际 Tab 入口、Enter/Space 打开与提交、方向键/Home/End/typeahead 导航、Escape 返回和不提交的 Tab 离开。原 selector.ts 保留绑定与异步结果归属;正常列表同步 aria-selected,包含原生交互 HTML 的内容保留按钮/输入框语义。鼠标悬停、异步结果、回调移交焦点及旧 click 参数均经过回归。 + +补充浏览器用例先复现再修复“已关闭列表继续吞掉 Escape”和“空列表悬停报告展开”。最终 CI 463 项、235 个生产 TS 严格检查通过;相关三浏览器回归 282 项通过,无失败/重试/跳过,其中选择列表专项 30 项。见 [阶段证据](baselines/keyboard-selectors-partial.json) 和 [实施记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。当前仍是源码构建证据,新安装包/legacy 全量验收尚待进行。 + +下一步设置树和面板切换焦点,再检查模式退出、动态控件移除/替换、跨实例/SSR/字幕。CORE-23 doing,BASE-DOM-01 open;57 done、1 doing、156 todo,最新完成提交仍 faaa3e8c。整个 CORE-23 验收后独立 commit;未推送或发布。 + +## 当前实施:CORE-23 进度与音量滑块阶段 + +进度/音量已有独立 TS 键盘范围模块,支持方向键、PageUp/PageDown、Home/End、范围禁用和 ARIA 同步;进度保留 setBar-before-seek 及可选指针参数,切源/销毁/嵌套操作取消旧写入。音量面板可通过 Tab 进入,修复 visibility 过渡导致快速 Tab 跳过滑块的问题。新增十二语言 Progress 翻译,公开字段可选,包与 Monaco 声明均由脚本再生成。 + +最终 CI 463 项、234 个生产 TS 严格检查通过;accessibility/hotkey/progress-quality 三浏览器 123 项通过,无失败/重试/跳过。WebKit 实际 seek 时间与目标的微小差值按实际媒体值校验;中途检出的 Monaco 声明遗漏已生成修复。具体失败、修正和来源见 [滑块阶段证据](baselines/keyboard-sliders-partial.json) 与 [实施记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。这是源码构建专项,尚非新安装包/legacy 全量验收。 + +接下来实现 selector、设置树和 Escape/焦点恢复,再检查模式退出、动态移除、跨实例/SSR/字幕。CORE-23 仍 doing,BASE-DOM-01 开放;57 done、1 doing、156 todo,最新完成提交仍 faaa3e8c。整个 CORE-23 完成后独立 commit;未推送或发布。 + +## 当前实施:CORE-23 按钮与键盘焦点第一阶段 + +从 faaa3e8c 接续,任务 doing。新增 accessibility/button、keyboard、focus 三个 TS 模块,接入播放、音量、设置、全屏/PiP/AirPlay/截图及自定义 click 控件;处理 Enter/Space、按键归属、焦点切换、动态移除和 scope 清理。新增键盘焦点样式,保留鼠标自动隐藏、旧点击回调和普通快捷键。 + +真实 Chromium 固定修改前 Tab 缺口;Firefox 探针确认其原生 video 是既有 Tab 入口,测试保留该入口后继续检查控件。新指针用例复现并修正了本轮任意焦点策略造成的控制栏常驻,现使用独立输入方式状态。当前完整 CI 456 项、232 个生产 TS 文件、按钮/焦点及 Hotkey 三浏览器 69 项通过。见 [阶段证据](baselines/keyboard-buttons-partial.json) 和 [变更记录](changes/2026-09-11-CORE-23-keyboard-focus.md)。 + +下一步实现/验证进度与音量 slider、selector、设置树进入/返回/Escape、模式退出、动态焦点恢复、跨实例/SSR 和字幕可用性,再进行安装包与全量矩阵验收。当前是源码构建浏览器证据,不能当作最新 npm/legacy 安装包已验证。CORE-23 与 BASE-DOM-01 保持开放,尚无本任务完成 commit;57 done、1 doing、156 todo。未推送或发布。 + ## 当前实施:CORE-21 公开声明生成与兼容视图完成 从 ee895a55 接续。公开声明源移至 packages/artplayer/public/,生成 37 个声明文件:22 个历史文件与精确模块/入口。新增 artplayer/runtime、runtime/legacy 和共享类型扩展入口,映射原有 JS 产物;build:types/check:types 已接入 CI 和隔离构建。旧入口继续支持 4.3.5,新精确入口验证 5.1.6/5.9.3 各四模式。核心自有源码 TS 迁移已在 CORE-20 完成,本任务完成公开类型出口与核心编辑器验收。 diff --git a/refactor/risk-table.md b/refactor/risk-table.md index e564ce4ed..a8a707104 100644 --- a/refactor/risk-table.md +++ b/refactor/risk-table.md @@ -10,7 +10,7 @@ | BASE-LIFE-03 | resolved / 已复现 | Async plugin registers its result after destroy | CORE-08 | | BASE-LIFE-04 | resolved / 已复现 | Destroying an instance twice unregisters a different live instance | CORE-04 | | BASE-LIFE-05 | resolved / 已复现 | Failed constructor leaves initialized markup/listeners until explicit probe cleanup | CORE-04 | -| BASE-DOM-01 | open / 已复现 | 控件 Tab 不可达 | CORE-23, CORE-17 | +| BASE-DOM-01 | resolved / 已复现 | 控件 Tab 不可达 | CORE-23, CORE-17 | | BASE-DOM-02 | resolved / 已复现 | 窄容器中控件裁切 | CORE-13, CORE-14 | | BASE-DEMO-01 | open / 源码/产物事实 | 旧 thumbnail 插件示例不对应当前 workspace 包 | SITE-01, EX-03 | | BASE-TYPE-01 | resolved / 已复现 | NodeNext ESM 默认导出与声明互操作失配 | ENG-04, CORE-07, PKG-CHAPTER-04 | diff --git a/refactor/risks.json b/refactor/risks.json index 4cc83b70a..794aa2c01 100644 --- a/refactor/risks.json +++ b/refactor/risks.json @@ -146,7 +146,7 @@ "id": "BASE-DOM-01", "title": "控件 Tab 不可达", "confirmation": "reproduced", - "status": "open", + "status": "resolved", "owners": [ "CORE-23", "CORE-17" @@ -155,7 +155,15 @@ "refactor/baselines/dom.json" ], "compatibleResolution": "补键盘可达性、焦点及名称,保留旧 DOM/CSS 和快捷键。", - "closureCriteria": "真实键盘与焦点回归通过,不只检查静态属性。" + "closureCriteria": "真实键盘与焦点回归通过,不只检查静态属性。", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-23-keyboard-focus.md", + "refactor/baselines/keyboard-validation.json", + "test/browser/accessibility.spec.js", + "test/browser/accessibility-setting.spec.js", + "test/browser/accessibility-integration.spec.js" + ], + "resolutionRationale": "旧发布包的 Tab 缺口保留对照;现有按钮、进度/音量滑块、选择列表、设置、mini、信息/锁定层及菜单具备真实键盘与焦点回归,保留旧快捷键和点击契约。新安装包 modern/legacy 各 1749 项三引擎全量通过,CI 468 项;动态入口失效先复现再修正。只关闭主要控件 Tab 不可达;物理 Apple/触摸/IME/辅助技术与 CORE-22/发布复盘仍为独立门槛。" }, { "id": "BASE-DOM-02", diff --git a/refactor/tasks.json b/refactor/tasks.json index dbe2dcbf8..9cf31da4a 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -1168,9 +1168,12 @@ "scope": [ "artplayer" ], - "status": "todo", + "status": "done", "risk": "H", - "evidence": [], + "evidence": [ + "changes/2026-09-11-CORE-23-keyboard-focus.md", + "baselines/keyboard-validation.json" + ], "id": "CORE-23", "phase": "3-4 核心迁移", "title": "检查并补齐键盘、焦点与可访问名称", diff --git a/test/accessibility-button.test.js b/test/accessibility-button.test.js new file mode 100644 index 000000000..5a32d87d8 --- /dev/null +++ b/test/accessibility-button.test.js @@ -0,0 +1,129 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Exercise owned keyboard interactions with the repository runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { keyboardButton, isClaimedKey, acceptsHotkey, ResourceScope } = await loadModules({ + keyboardButton: { file: 'packages/artplayer/src/accessibility/button', name: 'keyboardButton' }, + isClaimedKey: { file: 'packages/artplayer/src/accessibility/keyboard', name: 'isClaimedKey' }, + acceptsHotkey: { file: 'packages/artplayer/src/input/keyboard-focus', name: 'acceptsHotkey' }, + ResourceScope: 'packages/artplayer/src/lifecycle/scope', +}) + +class Button extends EventTarget { + attributes = new Map() + ownerDocument = { activeElement: this } + nodeType = 1 + tagName = 'DIV' + isContentEditable = false + hits = 0 + getAttribute(key) { return this.attributes.get(key) ?? null } + hasAttribute(key) { return this.attributes.has(key) } + setAttribute(key, value) { this.attributes.set(key, String(value)) } + click() { this.hits++ } +} + +function fixture() { + const scope = new ResourceScope() + const button = new Button() + keyboardButton(scope, button) + const key = (type, value, options = {}) => { + const event = Object.assign(new Event(type, { cancelable: true }), { key: value, ...options }) + button.dispatchEvent(event) + return event + } + return { scope, button, key } +} + +test('buttons activate Enter on press and Space on release without key-repeat duplicates', () => { + const { scope, button, key } = fixture() + assert.equal(button.getAttribute('role'), 'button') + assert.equal(button.tabIndex, 0) + assert.equal(key('keydown', 'Enter').defaultPrevented, true) + key('keydown', 'Enter', { repeat: true }) + key('keyup', 'Enter') + assert.equal(button.hits, 1) + key('keydown', ' ') + key('keydown', ' ', { repeat: true }) + assert.equal(button.hits, 1) + key('keyup', ' ') + key('keyup', ' ') + assert.equal(button.hits, 2) + scope.dispose() +}) + +test('owned button keys avoid hotkeys while unrelated prevented events keep the legacy policy', () => { + const { scope, button, key } = fixture() + const owned = key('keydown', ' ') + assert.equal(isClaimedKey(owned), true) + assert.equal(acceptsHotkey(owned, button.ownerDocument), false) + const external = new Event('keydown', { cancelable: true }) + external.preventDefault() + assert.equal(isClaimedKey(external), false) + assert.equal(acceptsHotkey(external, button.ownerDocument), true) + scope.dispose() +}) + +test('blur, modifiers, composition and disabled state cancel button activation', () => { + const { scope, button, key } = fixture() + key('keydown', ' ') + button.dispatchEvent(new Event('blur')) + key('keyup', ' ') + for (const options of [{ ctrlKey: true }, { altKey: true }, { metaKey: true }, { isComposing: true }]) { + key('keydown', 'Enter', options) + key('keydown', ' ', options) + key('keyup', ' ', options) + } + button.setAttribute('aria-disabled', 'true') + assert.equal(isClaimedKey(key('keydown', 'Enter')), true) + key('keydown', ' ') + key('keyup', ' ') + assert.equal(button.hits, 0) + scope.dispose() +}) + +test('disposal removes button listeners and invalidates an armed Space action', () => { + const { scope, button, key } = fixture() + key('keydown', ' ') + scope.dispose() + assert.equal(key('keyup', ' ').defaultPrevented, false) + assert.equal(key('keydown', 'Enter').defaultPrevented, false) + assert.equal(button.hits, 0) +}) + +test('suspended button scopes cannot activate or arm Space until resumed', () => { + const scope = new ResourceScope() + const button = new Button() + let active = false + keyboardButton(scope, button, () => button.click(), () => active) + const key = (type, value) => button.dispatchEvent(Object.assign(new Event(type, { cancelable: true }), { key: value })) + key('keydown', 'Enter') + key('keydown', ' ') + active = true + key('keyup', ' ') + assert.equal(button.hits, 0) + key('keydown', ' ') + active = false + key('keyup', ' ') + active = true + key('keyup', ' ') + assert.equal(button.hits, 0) + key('keydown', 'Enter') + assert.equal(button.hits, 1) + scope.dispose() +}) + +test('button setup preserves caller role and tab order and ignores descendant key events', () => { + const scope = new ResourceScope() + const button = new Button() + button.setAttribute('role', 'switch') + button.setAttribute('tabindex', '-1') + keyboardButton(scope, button) + assert.equal(button.getAttribute('role'), 'switch') + assert.equal(button.getAttribute('tabindex'), '-1') + const event = Object.assign(new Event('keydown', { cancelable: true }), { key: 'Enter', composedPath: () => [new Button(), button] }) + button.dispatchEvent(event) + assert.equal(event.defaultPrevented, false) + assert.equal(button.hits, 0) + scope.dispose() +}) diff --git a/test/accessibility-focus.test.js b/test/accessibility-focus.test.js new file mode 100644 index 000000000..e170e4cd8 --- /dev/null +++ b/test/accessibility-focus.test.js @@ -0,0 +1,110 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Verify focus modality ownership and document rebinding. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { focusVisibility, captureMovedFocus, ResourceScope } = await loadModules({ + focusVisibility: { file: 'packages/artplayer/src/accessibility/focus', name: 'focusVisibility' }, + captureMovedFocus: { file: 'packages/artplayer/src/accessibility/moved-focus', name: 'captureMovedFocus' }, + ResourceScope: 'packages/artplayer/src/lifecycle/scope', +}) + +test('DOM moves restore the same connected descendant and preserve externally moved focus', () => { + const body = {} + const outside = {} + const doc = { body, activeElement: null } + let count = 0 + const child = { ownerDocument: doc, isConnected: true, focus(options) { + assert.deepEqual(options, { preventScroll: true }) + count++ + doc.activeElement = this + } } + const root = { ownerDocument: doc, contains: target => target === child } + doc.activeElement = child + const restore = captureMovedFocus(root) + doc.activeElement = body + restore() + assert.equal(doc.activeElement, child) + restore() + assert.equal(count, 1) + doc.activeElement = outside + restore() + assert.equal(doc.activeElement, outside) + doc.activeElement = body + child.isConnected = false + restore() + assert.equal(count, 1) + child.isConnected = true + doc.activeElement = outside + const unrelated = captureMovedFocus(root) + doc.activeElement = body + unrelated() + assert.equal(count, 1) +}) + +function fixture() { + const scope = new ResourceScope() + const doc = Object.assign(new EventTarget(), { activeElement: null }) + const classes = new Set() + const child = {} + const root = Object.assign(new EventTarget(), { + ownerDocument: doc, + contains: value => value === child, + classList: { + contains: name => classes.has(name), + remove: name => classes.delete(name), + toggle: (name, active) => active ? classes.add(name) : classes.delete(name), + }, + }) + let shows = 0 + const focused = focusVisibility(scope, root, () => shows++) + const focus = () => { + root.ownerDocument.activeElement = child + root.dispatchEvent(new Event('focusin')) + } + return { scope, doc, root, child, classes, focused, focus, shows: () => shows } +} + +test('keyboard visibility follows actual focus without making pointer focus sticky', () => { + const f = fixture() + assert.equal(f.focused(), false) + f.focus() + assert.equal(f.focused(), true) + assert.equal(f.shows(), 1) + f.doc.dispatchEvent(new Event('mousedown')) + assert.equal(f.focused(), false) + assert.equal(f.classes.size, 0) + f.doc.dispatchEvent(new Event('keydown')) + assert.equal(f.focused(), true) + assert.equal(f.shows(), 2) + f.doc.dispatchEvent(new Event('keydown')) + assert.equal(f.shows(), 2) + f.doc.activeElement = null + f.root.dispatchEvent(new Event('focusout')) + assert.equal(f.focused(), false) + assert.equal(f.classes.size, 0) + f.scope.dispose() +}) + +test('moving a focused player rebinds modality listeners and disposal releases both documents', () => { + const f = fixture() + f.focus() + const next = Object.assign(new EventTarget(), { activeElement: null }) + f.root.ownerDocument = next + f.focus() + f.doc.dispatchEvent(new Event('mousedown')) + assert.equal(f.focused(), true) + next.dispatchEvent(new Event('touchstart')) + assert.equal(f.focused(), false) + next.dispatchEvent(new Event('keydown')) + assert.equal(f.focused(), true) + const shows = f.shows() + f.scope.dispose() + assert.equal(f.focused(), false) + assert.equal(f.classes.size, 0) + for (const target of [f.doc, next, f.root]) + target.dispatchEvent(new Event('keydown')) + f.focus() + assert.equal(f.shows(), shows) + assert.equal(f.classes.size, 0) +}) diff --git a/test/accessibility-slider.test.js b/test/accessibility-slider.test.js new file mode 100644 index 000000000..b36ba7243 --- /dev/null +++ b/test/accessibility-slider.test.js @@ -0,0 +1,237 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Exercise owned range interactions with the repository runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { keyboardSlider, isClaimedKey, ResourceScope, Emitter, beginLifecycle, getScope, beginSource, ownEntry, releaseEntry, installProgressKeyboard, currentTimeMix } = await loadModules({ + keyboardSlider: { file: 'packages/artplayer/src/accessibility/slider', name: 'keyboardSlider' }, + isClaimedKey: { file: 'packages/artplayer/src/accessibility/keyboard', name: 'isClaimedKey' }, + ResourceScope: 'packages/artplayer/src/lifecycle/scope', + Emitter: 'packages/artplayer/src/utils/emitter', + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, + beginSource: { file: 'packages/artplayer/src/source/operation', name: 'beginSource' }, + ownEntry: { file: 'packages/artplayer/src/component/resources', name: 'ownEntry' }, + releaseEntry: { file: 'packages/artplayer/src/component/resources', name: 'releaseEntry' }, + installProgressKeyboard: { file: 'packages/artplayer/src/control/progress/keyboard', name: 'installProgressKeyboard' }, + currentTimeMix: 'packages/artplayer/src/player/currentTimeMix', +}) + +class Slider extends EventTarget { + attributes = new Map() + setAttribute(key, value) { this.attributes.set(key, String(value)) } + getAttribute(key) { return this.attributes.get(key) } + press(key, options = {}) { + const event = Object.assign(new Event('keydown', { cancelable: true }), { key, ...options }) + this.dispatchEvent(event) + return event + } +} + +function fixture() { + const scope = new ResourceScope() + const element = new Slider() + const range = { min: 0, max: 100, value: 50, step: 5, text: value => `${value}%` } + const values = [] + const update = keyboardSlider(scope, element, 'Volume', () => range, (value) => { + values.push(value) + range.value = value + }, 'vertical') + return { scope, element, range, values, update } +} + +test('slider keys repeat, clamp and expose the value actually written', () => { + const f = fixture() + for (const [key, value] of [['ArrowRight', 55], ['ArrowUp', 60], ['ArrowLeft', 55], ['ArrowDown', 50], ['PageUp', 100], ['PageDown', 50], ['Home', 0], ['End', 100], ['ArrowUp', 100]]) { + assert.equal(isClaimedKey(f.element.press(key, { repeat: true })), true) + assert.equal(f.range.value, value) + assert.equal(f.element.getAttribute('aria-valuenow'), String(value)) + } + assert.equal(f.element.getAttribute('aria-orientation'), 'vertical') + assert.equal(f.element.getAttribute('aria-valuetext'), '100%') + f.scope.dispose() +}) + +test('unavailable ranges claim navigation without writing NaN or invoking player shortcuts', () => { + const f = fixture() + for (const max of [0, -1, Number.NaN, Infinity]) { + f.range.max = max + f.update() + assert.equal(f.element.getAttribute('aria-disabled'), 'true') + assert.equal(f.element.getAttribute('aria-valuenow'), '0') + assert.equal(f.element.getAttribute('aria-valuemax'), '0') + assert.equal(isClaimedKey(f.element.press('End')), true) + } + assert.deepEqual(f.values, []) + f.range.max = 100 + f.range.step = 0 + f.element.press('ArrowUp') + assert.deepEqual(f.values, []) + f.range.step = 5 + f.update() + assert.equal(f.element.getAttribute('aria-disabled'), 'false') + f.scope.dispose() +}) + +test('slider ignores modified, composing, descendant and externally prevented keys', () => { + const f = fixture() + for (const options of [{ ctrlKey: true }, { altKey: true }, { metaKey: true }, { isComposing: true }, { keyCode: 229 }, { composedPath: () => [new EventTarget()] }]) + assert.equal(isClaimedKey(f.element.press('ArrowUp', options)), false) + const prevented = Object.assign(new Event('keydown', { cancelable: true }), { key: 'ArrowUp' }) + prevented.preventDefault() + f.element.dispatchEvent(prevented) + for (const key of ['k', 'toString', 'Tab', 'Escape']) + assert.equal(isClaimedKey(f.element.press(key)), false) + assert.deepEqual(f.values, []) + f.scope.dispose() + assert.equal(f.element.press('ArrowUp').defaultPrevented, false) +}) + +test('slider stops DOM updates when a write destroys its scope', () => { + const scope = new ResourceScope() + const element = new Slider() + let value = 0 + keyboardSlider(scope, element, 'Range', () => ({ min: 0, max: 10, step: 1, value, text: String }), (next) => { + value = next + scope.dispose() + }) + element.press('ArrowUp') + assert.equal(value, 1) + assert.equal(element.getAttribute('aria-valuenow'), '0') + element.press('ArrowUp') + assert.equal(value, 1) +}) + +function progressFixture() { + const art = Object.assign(new Emitter(), { duration: 200, currentTime: 50, constructor: { SEEK_STEP: 5 }, i18n: { get: key => key } }) + const element = new Slider() + const effects = [] + Object.defineProperty(art, 'seek', { get: () => undefined, set(value) { + effects.push(['seek', value]) + art.currentTime = value + } }) + art.on('setBar', (...args) => effects.push(['setBar', ...args])) + beginLifecycle(art) + ownEntry(art, element) + installProgressKeyboard(art, element) + return { art, element, effects } +} + +test('progress keyboard preserves bar-before-seek and optional pointer payload', () => { + const f = progressFixture() + f.element.press('ArrowRight') + assert.deepEqual(f.effects, [['setBar', 'played', 55 / 200], ['seek', 55]]) + assert.equal(f.element.getAttribute('aria-valuetext'), '00:55 / 03:20') + f.art.currentTime = 60 + f.art.emit('video:timeupdate', new Event('timeupdate')) + assert.equal(f.element.getAttribute('aria-valuenow'), '60') + f.art.duration = Infinity + f.art.emit('video:durationchange', new Event('durationchange')) + assert.equal(f.element.getAttribute('aria-valuetext'), '00:00 / 00:00') + assert.equal(f.element.getAttribute('aria-disabled'), 'true') + getScope(f.art).dispose() +}) + +test('progress keyboard cancels after synchronous source replacement or entry disposal', () => { + for (const cancel of [f => beginSource(f.art), f => releaseEntry(f.element), f => getScope(f.art).dispose()]) { + const f = progressFixture() + f.art.on('setBar', () => cancel(f)) + f.element.press('ArrowRight') + assert.deepEqual(f.effects, [['setBar', 'played', 55 / 200]]) + getScope(f.art).dispose() + } +}) + +test('nested progress keyboard action supersedes the outer seek and removal releases subscriptions', () => { + const f = progressFixture() + f.art.once('setBar', () => f.element.press('End')) + f.element.press('ArrowRight') + assert.deepEqual(f.effects, [['setBar', 'played', 55 / 200], ['setBar', 'played', 1], ['seek', 200]]) + releaseEntry(f.element) + const before = f.element.getAttribute('aria-valuenow') + f.art.currentTime = 0 + f.art.emit('video:timeupdate', new Event('timeupdate')) + assert.equal(f.element.getAttribute('aria-valuenow'), before) + assert.equal(f.element.press('Home').defaultPrevented, false) + getScope(f.art).dispose() +}) + +function seekingFixture() { + const f = progressFixture() + let time = 50 + const writes = [] + const video = { + seeking: false, + get currentTime() { return time }, + set currentTime(value) { + writes.push(value) + time = value + this.seeking = true + }, + } + f.art.template = { $video: video } + currentTimeMix(f.art) + beginSource(f.art) + const finish = (value) => { + time = value + video.seeking = false + f.art.emit('video:seeked', new Event('seeked')) + } + return { ...f, video, writes, finish } +} + +test('progress corrects a native completion miss at most once without repeating public seek', () => { + const f = seekingFixture() + f.element.press('End') + f.element.press('PageDown') + f.finish(200) + assert.deepEqual(f.writes, [200, 150, 150]) + assert.equal(f.art.currentTime, 150) + f.finish(200) + f.art.emit('video:ended', new Event('ended')) + assert.deepEqual(f.writes, [200, 150, 150]) + assert.deepEqual(f.effects, [ + ['setBar', 'played', 1], + ['seek', 200], + ['setBar', 'played', 0.75], + ['seek', 150], + ]) + assert.equal(f.element.getAttribute('aria-valuenow'), '200') + getScope(f.art).dispose() +}) + +test('public position changes supersede a pending progress correction', () => { + for (const nested of [false, true]) { + const f = seekingFixture() + // setBar is public and can replace the intended seek before its setter runs. + if (nested) { + f.art.once('setBar', () => { + f.art.currentTime = 30 + }) + } + f.element.press('ArrowRight') + if (!nested) + f.art.currentTime = 30 + f.finish(30) + assert.equal(f.art.currentTime, 30) + assert.deepEqual(f.writes, nested ? [30] : [55, 30]) + getScope(f.art).dispose() + } +}) + +test('source replacement, control removal and destruction release pending progress correction', () => { + for (const cancel of [f => beginSource(f.art), f => releaseEntry(f.element), f => getScope(f.art).dispose()]) { + const f = seekingFixture() + const listenerCount = () => (f.art.e['video:seeked'] || []).length + const before = listenerCount() + f.element.press('ArrowRight') + assert.equal(listenerCount(), before + 1) + cancel(f) + assert(listenerCount() <= before) + f.finish(0) + f.art.emit('video:ended', new Event('ended')) + assert.deepEqual(f.writes, [55]) + assert.equal(f.art.currentTime, 0) + getScope(f.art).dispose() + } +}) diff --git a/test/browser/accessibility-contextmenu.spec.js b/test/browser/accessibility-contextmenu.spec.js new file mode 100644 index 000000000..ccd7ba1a4 --- /dev/null +++ b/test/browser/accessibility-contextmenu.spec.js @@ -0,0 +1,278 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, options = {}) { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate((options) => { + window.menuCalls = [] + window.menuEvents = [] + window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, fullscreenWeb: true, ...options }) + window.art.on('contextmenu', value => window.menuEvents.push(value)) + }, options) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.locator('.art-control-playAndPause').focus() +} + +test('candidate: Shift F10 opens the default info action and closing info returns to the original control', async ({ page }) => { + await setup(page) + await page.keyboard.press('Shift+F10') + await expect(page.locator('.art-contextmenu-info')).toBeFocused() + expect(await page.evaluate(() => window.menuEvents)).toEqual([true]) + await page.keyboard.press('Enter') + await expect(page.locator('.art-info-close')).toBeFocused() + await expect(page.locator('.art-contextmenus')).toBeHidden() + await page.keyboard.press('Escape') + await expect(page.locator('.art-control-playAndPause')).toBeFocused() + expect(await page.evaluate(() => window.art.playing)).toBe(false) +}) + +test('candidate: context menu Escape closes before fullscreen and Tab continues from its origin', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.fullscreenWeb = true + }) + await page.keyboard.press('ContextMenu') + await expect(page.locator('.art-contextmenu-info')).toBeFocused() + await page.keyboard.press('Escape') + await expect(page.locator('.art-control-playAndPause')).toBeFocused() + expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(true) + await page.keyboard.press('Shift+F10') + await page.keyboard.press('Tab') + await expect(page.locator('.art-contextmenus')).toBeHidden() + await expect(page.locator('.art-icon-volumeClose')).toBeFocused() +}) + +test('candidate: keyboard choice navigation waits for activation and retains existing selection events', async ({ page }) => { + await setup(page, { playbackRate: true, aspectRatio: true, flip: true }) + await page.keyboard.press('Shift+F10') + const choices = page.locator('.art-contextmenu-playbackRate [data-value]') + await expect(choices.first()).toBeFocused() + await page.keyboard.press('ArrowRight') + await expect(choices.nth(1)).toBeFocused() + expect(await page.evaluate(() => window.art.playbackRate)).toBe(1) + const value = Number(await choices.nth(1).getAttribute('data-value')) + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => window.art.playbackRate)).toBe(value) + await expect(page.locator('.art-control-playAndPause')).toBeFocused() + await page.keyboard.press('Shift+F10') + await expect(choices.nth(1)).toHaveAttribute('aria-pressed', 'true') +}) + +test('candidate: custom context actions retain callbacks, typeahead and focus across replacement', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + for (const name of ['Alpha', 'Beta']) { + window.art.contextmenu.add({ name, html: name, click(menu, event) { + window.menuCalls.push([name, this === window.art, menu === window.art.contextmenu, event.type, menu.show]) + } }) + } + }) + await page.keyboard.press('Shift+F10') + await page.keyboard.press('b') + await expect(page.locator('.art-contextmenu-Beta')).toBeFocused() + await page.keyboard.press('Enter') + expect(await page.evaluate(() => window.menuCalls)).toEqual([['Beta', true, true, 'click', true]]) + await expect(page.locator('.art-contextmenus')).toBeVisible() + expect(await page.evaluate(() => window.art.contextmenu.update({ name: 'Beta', html: 'Updated Beta' }) === window.art.contextmenu.Beta)).toBe(true) + await expect(page.locator('.art-contextmenu-Beta')).toBeFocused() + expect(await page.locator('.art-contextmenu-Beta').evaluate(element => element.nextElementSibling.className)).toBe('art-contextmenu art-contextmenu-info') + await page.evaluate(() => window.art.contextmenu.remove('Beta')) + await expect(page.locator('.art-contextmenu-info')).toBeFocused() +}) + +test('candidate: native context content retains input editing and button activation without nested roles', async ({ page }) => { + await setup(page) + await page.evaluate(() => window.art.contextmenu.add({ name: 'native', html: '', click(menu, event) { + if (event.target.id === 'menu-native') + window.menuCalls.push(['native']) + } })) + await page.keyboard.press('Shift+F10') + await page.locator('#menu-input').focus() + await page.keyboard.type('typed text') + await page.keyboard.press('ArrowLeft') + await expect(page.locator('#menu-input')).toHaveValue('typed text') + expect(await page.evaluate(() => window.art.currentTime)).toBe(0) + await page.locator('#menu-native').focus() + await expect(page.locator('.art-contextmenu-native')).not.toHaveAttribute('role', 'button') + await page.keyboard.press('Space') + expect(await page.evaluate(() => window.menuCalls)).toEqual([['native']]) +}) + +test('candidate: disabled context menus do not claim the keyboard opening gesture', async ({ page }) => { + await setup(page) + expect(await page.evaluate(() => { + window.Artplayer.CONTEXTMENU = false + const event = new KeyboardEvent('keydown', { key: 'F10', shiftKey: true, bubbles: true, cancelable: true }) + window.art.controls.playAndPause.dispatchEvent(event) + return { prevented: event.defaultPrevented, shown: window.art.contextmenu.show } + })).toEqual({ prevented: false, shown: false }) +}) + +test('candidate: a hidden or disabled origin falls back to the player and outside focus is preserved', async ({ page }) => { + await setup(page) + for (const unavailable of ['hidden', 'disabled', 'removed']) { + await page.evaluate(() => window.art.controls.add({ name: 'origin', position: 'left', html: 'Origin', click() {} })) + await page.locator('.art-control-origin').focus() + await page.keyboard.press('Shift+F10') + await page.evaluate((unavailable) => { + const origin = window.art.controls.origin + if (unavailable === 'hidden') + origin.style.visibility = 'hidden' + else if (unavailable === 'disabled') + origin.setAttribute('aria-disabled', 'true') + else + origin.remove() + }, unavailable) + await page.keyboard.press('Escape') + await expect(page.locator('.art-video-player')).toBeFocused() + await page.evaluate(() => window.art.controls.remove('origin')) + } + await page.locator('.art-control-playAndPause').focus() + await page.keyboard.press('Shift+F10') + await page.locator('#play').focus() + await expect(page.locator('.art-contextmenus')).toBeHidden() + await expect(page.locator('#play')).toBeFocused() +}) + +test('candidate: menu reinitialization replaces listeners and a rejected duplicate initialization keeps them', async ({ page }) => { + await setup(page) + expect(await page.evaluate(() => { + const menu = window.art.contextmenu + try { + menu.init() + } + catch (error) { + return error.message.includes('existing [info]') + } + return false + })).toBe(true) + await page.keyboard.press('Shift+F10') + await expect(page.locator('.art-contextmenu-info')).toBeFocused() + await page.keyboard.press('Escape') + await page.evaluate(() => { + const menu = window.art.contextmenu + for (const name of [...menu.cache.keys()]) + menu.remove(name) + menu.init() + window.menuEvents = [] + }) + await page.keyboard.press('Shift+F10') + await expect(page.locator('.art-contextmenu-info')).toBeFocused() + expect(await page.evaluate(() => window.menuEvents)).toEqual([true]) + await page.keyboard.press('Escape') + expect(await page.evaluate(() => window.menuEvents)).toEqual([true, false]) + await expect(page.locator('.art-control-playAndPause')).toBeFocused() +}) + +test('candidate: menu activation preserves callback focus transfers and destruction leaves detached controls inert', async ({ page }) => { + await setup(page) + await page.evaluate(() => window.art.contextmenu.add({ name: 'outside', html: 'Outside', click(menu) { + document.querySelector('#play').focus() + menu.show = false + } })) + await page.keyboard.press('Shift+F10') + await page.keyboard.press('Enter') + await expect(page.locator('#play')).toBeFocused() + await expect(page.locator('.art-contextmenus')).toBeHidden() + await page.evaluate(() => { + window.art.contextmenu.update({ name: 'outside', click() { + window.menuCalls.push('destroy') + this.destroy() + } }) + window.detachedMenu = window.art.contextmenu.outside + }) + await page.locator('.art-control-playAndPause').focus() + await page.keyboard.press('Shift+F10') + await page.keyboard.press('Space') + expect(await page.evaluate(() => { + window.detachedMenu.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })) + window.detachedMenu.click() + return { calls: window.menuCalls, instances: window.Artplayer.instances.length, focused: document.activeElement.tagName } + })).toEqual({ calls: ['destroy'], instances: 0, focused: 'BODY' }) +}) + +test('candidate: native editable context gestures remain native while pointer opening preserves external focus', async ({ page }) => { + await setup(page) + await page.evaluate(() => window.art.controls.add({ name: 'input', position: 'left', html: '' })) + await page.locator('#context-input').focus() + expect(await page.evaluate(() => { + const input = document.querySelector('#context-input') + const key = new KeyboardEvent('keydown', { key: 'F10', shiftKey: true, bubbles: true, cancelable: true }) + const pointer = new MouseEvent('contextmenu', { bubbles: true, cancelable: true }) + input.dispatchEvent(key) + input.dispatchEvent(pointer) + return { key: key.defaultPrevented, pointer: pointer.defaultPrevented, shown: window.art.contextmenu.show } + })).toEqual({ key: false, pointer: false, shown: false }) + await page.locator('#play').focus() + expect(await page.evaluate(() => { + const event = new MouseEvent('contextmenu', { clientX: 200, clientY: 120, bubbles: true, cancelable: true }) + window.art.template.$player.dispatchEvent(event) + return event.defaultPrevented + })).toBe(true) + await expect(page.locator('.art-contextmenus')).toBeVisible() + await expect(page.locator('#play')).toBeFocused() + await page.evaluate(() => { + window.art.contextmenu.show = false + }) + await expect(page.locator('#play')).toBeFocused() +}) + +test('candidate: keyboard menu remains inside the player and ignores a canceled opening', async ({ page }, testInfo) => { + await setup(page, { playbackRate: true, aspectRatio: true, flip: true, lang: 'zh-cn' }) + await page.evaluate(() => { + window.art.on('contextmenu', function cancel(show) { + if (show) { + window.art.off('contextmenu', cancel) + window.art.contextmenu.show = false + } + }) + }) + await page.keyboard.press('Shift+F10') + await expect(page.locator('.art-contextmenus')).toBeHidden() + await expect(page.locator('.art-control-playAndPause')).toBeFocused() + await page.keyboard.press('Shift+F10') + await expect(page.locator('.art-contextmenus')).toHaveAttribute('aria-label', '快捷菜单') + expect(await page.evaluate(() => { + const menu = window.art.template.$contextmenu.getBoundingClientRect() + const player = window.art.template.$player.getBoundingClientRect() + return menu.left >= player.left && menu.right <= player.right && menu.top >= player.top && menu.bottom <= player.bottom + })).toBe(true) + await page.locator('.art-video-player').screenshot({ path: `refactor/.cache/core23-contextmenu-keyboard-${testInfo.project.name}.png` }) +}) + +test('candidate: custom menu handoff to mini returns to the control that opened the menu', async ({ page }) => { + await setup(page) + await page.evaluate(() => window.art.contextmenu.add({ name: 'mini', html: 'Mini', click(menu) { + this.mini = true + menu.show = false + } })) + await page.keyboard.press('Shift+F10') + await expect(page.locator('.art-contextmenu-mini')).toBeFocused() + await page.keyboard.press('Enter') + await expect(page.locator('.art-mini-close')).toBeFocused() + await expect(page.locator('.art-contextmenus')).toBeHidden() + await page.keyboard.press('Escape') + await expect(page.locator('.art-mini-popup')).toBeHidden() + await expect(page.locator('.art-control-playAndPause')).toBeFocused() +}) + +test('candidate: context keyboard and focus ownership stay local to each player', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + const container = document.createElement('div') + container.id = 'second-player' + container.style.cssText = 'width:640px;height:360px' + document.body.append(container) + window.otherArt = new window.Artplayer({ container, url: '/test/pattern.mp4', muted: true }) + }) + await expect.poll(() => page.evaluate(() => window.otherArt.isReady)).toBe(true) + await page.keyboard.press('Shift+F10') + await expect(page.locator('.player .art-contextmenu-info')).toBeFocused() + await page.locator('#second-player .art-control-playAndPause').focus() + await expect(page.locator('.player .art-contextmenus')).toBeHidden() + await page.keyboard.press('Shift+F10') + await expect(page.locator('#second-player .art-contextmenu-info')).toBeFocused() + await page.evaluate(() => window.art.destroy()) + await page.keyboard.press('Escape') + await expect(page.locator('#second-player .art-control-playAndPause')).toBeFocused() + expect(await page.evaluate(() => window.otherArt.playing)).toBe(false) +}) diff --git a/test/browser/accessibility-controls.spec.js b/test/browser/accessibility-controls.spec.js new file mode 100644 index 000000000..57f3ba0fc --- /dev/null +++ b/test/browser/accessibility-controls.spec.js @@ -0,0 +1,168 @@ +import { expect, test } from './fixtures.js' + +async function setup(page) { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => { + window.focusCalls = [] + window.focusOrder = [] + const outside = document.createElement('button') + outside.id = 'outside-focus' + outside.textContent = 'Outside' + document.body.append(outside) + window.art = new window.Artplayer({ + container: '.player', + url: '/test/pattern.mp4', + muted: true, + controls: ['first', 'second', 'third'].map((name, index) => ({ + name, + index: index + 10, + position: 'right', + html: name, + click(component, event) { + window.focusCalls.push([name, this === window.art, component === window.art.controls, event.type]) + }, + })), + }) + window.art.template.$player.addEventListener('focusin', event => window.focusOrder.push(event.target.className)) + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +const control = (page, name) => page.locator(`.art-control-${name}`) + +test('candidate: replacing a focused control restores its new entry without intermediate focus', async ({ page }) => { + await setup(page) + await control(page, 'first').focus() + const result = await page.evaluate(() => { + window.focusOrder.length = 0 + return window.art.controls.update({ name: 'first', html: 'Updated' }) + }) + expect(result).toBeUndefined() + await expect(control(page, 'first')).toBeFocused() + expect(await page.evaluate(() => window.focusOrder)).toEqual(['art-control art-control-first']) + await page.keyboard.press('Space') + expect(await page.evaluate(() => window.focusCalls)).toEqual([['first', true, true, 'click']]) +}) + +test('candidate: removing a focused control chooses a surviving neighbor and preserves external focus', async ({ page }) => { + await setup(page) + await control(page, 'first').focus() + await page.evaluate(() => window.art.controls.remove('first')) + await expect(control(page, 'second')).toBeFocused() + await control(page, 'third').focus() + await page.evaluate(() => window.art.controls.remove('third')) + await expect(control(page, 'second')).toBeFocused() + await page.locator('#outside-focus').focus() + await page.evaluate(() => window.art.controls.remove('second')) + await expect(page.locator('#outside-focus')).toBeFocused() +}) + +test('candidate: failed control replacement recovers focus but a veto keeps the original focused entry', async ({ page }) => { + await setup(page) + await control(page, 'first').focus() + expect(await page.evaluate(() => { + try { + window.art.controls.update({ name: 'first', mounted() { + throw new Error('mount failed') + } }) + } + catch (error) { return error.message } + })).toBe('mount failed') + await expect(control(page, 'second')).toBeFocused() + expect(await page.evaluate(() => { + try { + window.art.controls.update({ name: 'second', beforeUnmount() { + throw new Error('veto') + } }) + } + catch (error) { return error.message } + })).toBe('veto') + await expect(control(page, 'second')).toBeFocused() +}) + +test('candidate: callbacks can transfer focus outside without an intermediate or final control focus', async ({ page }) => { + await setup(page) + for (const phase of ['beforeUnmount', 'mounted']) { + await control(page, 'first').focus() + await page.evaluate((phase) => { + window.focusOrder.length = 0 + window.art.controls.update({ name: 'first', beforeUnmount: undefined, mounted: undefined, [phase]() { + document.querySelector('#outside-focus').focus() + } }) + }, phase) + await expect(page.locator('#outside-focus')).toBeFocused() + expect(await page.evaluate(() => window.focusOrder)).toEqual([]) + } +}) + +test('candidate: replacing a focused selector option transfers focus to the new control', async ({ page }) => { + await setup(page) + await page.evaluate(() => window.art.controls.update({ name: 'first', click: undefined, selector: [{ html: 'Auto', default: true }, { html: 'HD' }], onSelect: item => item.html })) + await control(page, 'first').locator('.art-selector-value').focus() + await page.keyboard.press('Enter') + await expect(control(page, 'first').locator('.art-selector-item').first()).toBeFocused() + await page.evaluate(() => window.art.controls.update({ name: 'first', selector: undefined, html: 'Button', click() {} })) + await expect(control(page, 'first')).toBeFocused() +}) + +test('candidate: removing the last focusable control leaves focus on the player without an extra sequential Tab stop', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + for (const name of [...window.art.controls.cache.keys()]) { + if (name !== 'first') + window.art.controls.remove(name) + } + }) + await control(page, 'first').focus() + await page.evaluate(() => window.art.controls.remove('first')) + await expect(page.locator('.art-video-player')).toBeFocused() + await expect(page.locator('.art-video-player')).toHaveAttribute('tabindex', '-1') + await page.evaluate(() => window.art.destroy(false)) + await expect(page.locator('.art-video-player')).not.toHaveAttribute('tabindex') +}) + +test('candidate: focus recovery skips unavailable controls and uses a replacement native button', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.controls.second.style.visibility = 'hidden' + window.art.controls.third.setAttribute('aria-disabled', 'true') + }) + await control(page, 'first').focus() + await page.evaluate(() => window.art.controls.update({ name: 'first', html: '' })) + await expect(control(page, 'first').locator('button')).toBeFocused() + await expect(control(page, 'first')).not.toHaveAttribute('role', 'button') + await page.keyboard.press('Space') + expect(await page.evaluate(() => window.focusCalls)).toEqual([['first', true, true, 'click']]) + await page.evaluate(() => window.art.controls.remove('first')) + await expect(page.locator('.art-icon-volumeClose')).toBeFocused() +}) + +test('candidate: an unrelated instance update cannot take focus from another player', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + const container = document.createElement('div') + container.style.cssText = 'width:640px;height:360px' + document.body.append(container) + window.secondArt = new window.Artplayer({ container, url: '/test/pattern.mp4', muted: true, controls: [{ name: 'custom', position: 'right', html: 'Other', click() {} }] }) + }) + await control(page, 'first').focus() + await page.evaluate(() => window.secondArt.controls.update({ name: 'custom', html: 'Changed' })) + await expect(control(page, 'first')).toBeFocused() + await control(page, 'custom').focus() + await page.evaluate(() => window.art.controls.remove('first')) + await expect(control(page, 'custom')).toBeFocused() +}) + +test('candidate: a disabled native replacement falls back and focus callbacks can destroy the player', async ({ page }) => { + await setup(page) + await control(page, 'first').focus() + await page.evaluate(() => window.art.controls.update({ name: 'first', html: '
' })) + await expect(control(page, 'second')).toBeFocused() + await page.evaluate(() => window.art.controls.update({ name: 'second', mounted(element) { + window.retainedControl = element + element.addEventListener('focus', () => window.art.destroy(false), { once: true }) + } })) + expect(await page.evaluate(() => window.art.isDestroy)).toBe(true) + await page.evaluate(() => window.retainedControl.click()) + expect(await page.evaluate(() => window.focusCalls)).toEqual([]) +}) diff --git a/test/browser/accessibility-info.spec.js b/test/browser/accessibility-info.spec.js new file mode 100644 index 000000000..b61462a8b --- /dev/null +++ b/test/browser/accessibility-info.spec.js @@ -0,0 +1,136 @@ +import { expect, test } from './fixtures.js' + +async function setup(page) { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => { + window.infoEvents = [] + const outside = document.createElement('button') + outside.id = 'info-outside' + outside.textContent = 'Outside' + document.body.append(outside) + window.art = new window.Artplayer({ + container: '.player', + url: '/test/pattern.mp4', + muted: true, + fullscreenWeb: true, + controls: [{ name: 'info-trigger', position: 'right', html: 'Info', click() { this.info.show = true } }], + }) + window.art.on('info', value => window.infoEvents.push(value)) + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +test('candidate: info keyboard entry, Space close and Escape preserve the opening control', async ({ page }) => { + await setup(page) + const trigger = page.locator('.art-control-info-trigger') + await trigger.focus() + await page.keyboard.press('Enter') + await expect(page.locator('.art-info-close')).toBeFocused() + await expect(page.locator('.art-info-close')).toHaveAttribute('aria-label', 'Close') + await expect(page.locator('.art-info')).toHaveAttribute('aria-label', 'Video Info') + await page.keyboard.press('Space') + await expect(page.locator('.art-info')).toBeHidden() + await expect(trigger).toBeFocused() + await page.evaluate(() => { + window.art.fullscreenWeb = true + }) + await page.keyboard.press('Enter') + await expect(page.locator('.art-info-close')).toBeFocused() + await page.keyboard.press('Escape') + await expect(page.locator('.art-info')).toBeHidden() + await expect(trigger).toBeFocused() + expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(true) + await page.keyboard.press('Escape') + expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(false) + expect(await page.evaluate(() => window.infoEvents)).toEqual([true, false, true, false]) +}) + +test('candidate: info pointer and programmatic visibility preserve unrelated focus', async ({ page }) => { + await setup(page) + await page.locator('.art-control-info-trigger').click() + await expect(page.locator('.art-info-close')).not.toBeFocused() + await page.locator('#info-outside').focus() + await page.evaluate(() => { + window.art.info.show = false + window.art.info.show = true + window.art.info.show = false + }) + await expect(page.locator('#info-outside')).toBeFocused() +}) + +test('candidate: repeated info init replaces keyboard bindings and retains the current return target', async ({ page }) => { + await setup(page) + await page.locator('.art-control-info-trigger').focus() + await page.keyboard.press('Enter') + await page.evaluate(() => { + window.art.info.init() + window.art.info.init() + window.infoEvents.length = 0 + }) + await page.keyboard.press('Enter') + await expect(page.locator('.art-info')).toBeHidden() + await expect(page.locator('.art-control-info-trigger')).toBeFocused() + expect(await page.evaluate(() => window.infoEvents)).toEqual([false]) +}) + +test('candidate: info with a removed origin returns to the player and destruction disables retained controls', async ({ page }) => { + await setup(page) + await page.locator('.art-control-info-trigger').focus() + await page.keyboard.press('Enter') + await page.evaluate(() => window.art.controls.remove('info-trigger')) + await page.keyboard.press('Escape') + await expect(page.locator('.art-video-player')).toBeFocused() + await page.evaluate(() => { + window.retainedInfo = window.art.template.$infoClose + window.art.destroy(false) + window.infoEvents.length = 0 + window.retainedInfo.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })) + window.retainedInfo.click() + }) + expect(await page.evaluate(() => window.infoEvents)).toEqual([]) +}) + +for (const core of ['published', 'candidate']) { + test(`${core}: optional SSR info wrapper may be absent without preventing polling and close`, async ({ page }) => { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + expect(await page.evaluate(() => { + const container = document.querySelector('.player') + container.innerHTML = window.Artplayer.html + container.querySelector('.art-info').className = 'caller-info' + const close = container.querySelector('.art-info-close') + const panel = container.querySelector('.art-info-panel') + const art = new window.Artplayer({ container, url: '', useSSR: true }) + art.info.show = true + close.click() + const result = { absent: art.template.$info === null, retained: art.template.$infoClose === close && art.template.$infoPanel === panel, closed: !art.info.show } + art.destroy() + return result + })).toEqual({ absent: true, retained: true, closed: true }) + }) +} + +test('candidate: failed info name initialization releases its handlers and permits a clean retry', async ({ page }) => { + await setup(page) + expect(await page.evaluate(() => { + const get = window.art.i18n.get + const count = window.art.e.info.length + const failure = new Error('name failed') + window.art.i18n.get = () => { + throw failure + } + let same = false + try { + window.art.info.init() + } + catch (error) { same = error === failure } + window.art.i18n.get = get + const released = window.art.e.info.length === count - 1 + window.art.info.init() + return { same, released } + })).toEqual({ same: true, released: true }) + await page.locator('.art-control-info-trigger').focus() + await page.keyboard.press('Enter') + await expect(page.locator('.art-info-close')).toBeFocused() + await page.keyboard.press('Escape') + await expect(page.locator('.art-control-info-trigger')).toBeFocused() +}) diff --git a/test/browser/accessibility-integration.spec.js b/test/browser/accessibility-integration.spec.js new file mode 100644 index 000000000..21f16b551 --- /dev/null +++ b/test/browser/accessibility-integration.spec.js @@ -0,0 +1,130 @@ +import { expect, test } from './fixtures.js' + +async function setup(page) { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => { + window.modeEvents = [] + window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, fullscreen: true, fullscreenWeb: true, pip: true }) + window.art.on('fullscreen', value => window.modeEvents.push(['fullscreen', value])) + window.art.on('pip', value => window.modeEvents.push(['pip', value])) + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +test('candidate: native fullscreen keyboard activation retains focus through entry and exit', async ({ page }) => { + await setup(page) + const trigger = page.locator('.art-control-fullscreen') + await trigger.focus() + await page.keyboard.press('Enter') + await expect.poll(() => page.evaluate(() => window.art.fullscreen)).toBe(true) + await expect(trigger).toBeFocused() + await expect(trigger).toHaveAttribute('aria-label', 'Exit Fullscreen') + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => window.art.fullscreen)).toBe(false) + await expect(trigger).toBeFocused() + await expect(trigger).toHaveAttribute('aria-label', 'Fullscreen') + expect(await page.evaluate(() => ({ events: window.modeEvents, playing: window.art.playing }))).toEqual({ events: [['fullscreen', true], ['fullscreen', false]], playing: false }) +}) + +test('candidate: native fullscreen external exit preserves the current in-player focus', async ({ page }) => { + await setup(page) + await page.locator('.art-control-fullscreen').focus() + await page.keyboard.press('Enter') + await expect.poll(() => page.evaluate(() => window.art.fullscreen)).toBe(true) + const play = page.locator('.art-control-playAndPause') + await play.focus() + await page.evaluate(async () => { + const exit = ['exitFullscreen', 'webkitExitFullscreen', 'webkitCancelFullScreen', 'mozCancelFullScreen', 'msExitFullscreen'].find(name => name in document) + await document[exit]() + }) + await expect.poll(() => page.evaluate(() => window.art.fullscreen)).toBe(false) + await expect(play).toBeFocused() + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => window.art.playing)).toBe(true) +}) + +test('candidate: PiP keyboard control follows real native capability without a second playback action', async ({ page }, testInfo) => { + await setup(page) + const capability = await page.evaluate(() => ({ + standard: !!document.pictureInPictureEnabled && typeof window.art.video.requestPictureInPicture === 'function', + webkit: typeof window.art.video.webkitSetPresentationMode === 'function', + })) + await testInfo.attach('native-pip-capability', { contentType: 'application/json', body: JSON.stringify(capability) }) + const trigger = page.locator('.art-control-pip') + await trigger.focus() + await page.keyboard.press('Enter') + if (capability.standard || capability.webkit) { + await expect.poll(() => page.evaluate(() => !!window.art.pip)).toBe(true) + await expect(trigger).toBeFocused() + await expect(trigger).toHaveAttribute('aria-label', 'Exit PIP Mode') + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => !!window.art.pip)).toBe(false) + await expect(trigger).toBeFocused() + await expect(trigger).toHaveAttribute('aria-label', 'PIP Mode') + expect(await page.evaluate(() => window.modeEvents)).toEqual([['pip', true], ['pip', false]]) + } + else { + await expect(page.locator('.art-notice')).toBeVisible() + await expect(trigger).toBeFocused() + expect(await page.evaluate(() => !!window.art.pip)).toBe(false) + expect(await page.evaluate(() => window.modeEvents)).toEqual([]) + } + expect(await page.evaluate(() => window.art.playing)).toBe(false) +}) + +test('candidate: SSR retains native nodes while keyboard controls toggle real subtitle cues and survive fullscreen', async ({ page }, testInfo) => { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => { + const container = document.querySelector('.player') + container.innerHTML = window.Artplayer.html + window.ssrPlayer = container.querySelector('.art-video-player') + window.ssrVideo = container.querySelector('video') + window.ssrSubtitle = container.querySelector('.art-subtitle') + window.art = new window.Artplayer({ + container, + useSSR: true, + url: '/test/pattern.mp4', + muted: true, + fullscreenWeb: true, + subtitle: { url: '/test/declaration-cues.vtt', name: 'English captions' }, + controls: [{ name: 'captions', position: 'left', html: 'Captions', click() { + this.subtitle.show = !this.subtitle.show + } }], + }) + }) + await expect.poll(() => page.evaluate(() => window.art.isReady && window.art.subtitle.cues.length === 1)).toBe(true) + const play = page.locator('.art-control-playAndPause') + await play.focus() + await page.keyboard.press('Space') + await expect(page.locator('.art-subtitle-line')).toHaveText('Declaration cue') + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => window.art.playing)).toBe(false) + const captions = page.locator('.art-control-captions') + await captions.focus() + await page.keyboard.press('Enter') + await expect(page.locator('.art-subtitle')).toBeHidden() + await expect(captions).toBeFocused() + await page.keyboard.press('Space') + await expect(page.locator('.art-subtitle-line')).toBeVisible() + await expect(captions).toBeFocused() + const fullscreen = page.locator('.art-control-fullscreenWeb') + await fullscreen.focus() + await page.keyboard.press('Enter') + await expect.poll(() => page.evaluate(() => window.art.fullscreenWeb)).toBe(true) + await expect(fullscreen).toBeFocused() + await expect(page.locator('.art-subtitle-line')).toBeVisible() + await page.keyboard.press('Escape') + await expect.poll(() => page.evaluate(() => window.art.fullscreenWeb)).toBe(false) + await expect(fullscreen).toBeFocused() + expect(await page.evaluate(() => ({ + player: window.ssrPlayer === window.art.template.$player, + video: window.ssrVideo === window.art.video, + subtitle: window.ssrSubtitle === window.art.template.$subtitle, + label: window.art.template.$track.label, + focusInSubtitle: !!window.ssrSubtitle.querySelector('[tabindex],button,input'), + live: window.ssrSubtitle.hasAttribute('aria-live'), + }))).toEqual({ player: true, video: true, subtitle: true, label: 'English captions', focusInSubtitle: false, live: false }) + await page.locator('.art-video-player').screenshot({ path: `refactor/.cache/core23-ssr-subtitle-${testInfo.project.name}.png` }) + await page.evaluate(() => window.art.destroy(false)) + expect(await page.evaluate(() => window.ssrVideo.isConnected && window.ssrPlayer.classList.contains('art-destroy'))).toBe(true) +}) diff --git a/test/browser/accessibility-lock.spec.js b/test/browser/accessibility-lock.spec.js new file mode 100644 index 000000000..9cea626cd --- /dev/null +++ b/test/browser/accessibility-lock.spec.js @@ -0,0 +1,127 @@ +import { expect, test } from './fixtures.js' + +async function setup(page) { + await page.addInitScript(() => Object.defineProperty(navigator, 'userAgent', { configurable: true, value: 'ArtPlayer Android keyboard fixture' })) + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => { + const outside = document.createElement('button') + outside.id = 'lock-outside' + outside.textContent = 'Outside' + document.body.append(outside) + window.lockEvents = [] + window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, lock: true, hotkey: true }) + window.art.on('lock', value => window.lockEvents.push([value, window.art.isLock, window.art.plugins.lock.state])) + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +test('candidate: lock uses one stable keyboard button, Escape unlocks and hidden controls leave Tab order', async ({ page }) => { + await setup(page) + const lock = page.locator('.art-layer-lock') + await lock.focus() + await expect(lock).toBeFocused() + await expect(lock).toHaveAttribute('aria-label', 'Lock') + await page.keyboard.press('Space') + await expect(lock).toHaveAttribute('aria-pressed', 'true') + await expect(lock).toBeFocused() + await page.keyboard.press('Tab') + await expect(page.locator('#play')).toBeFocused() + await page.keyboard.press('Shift+Tab') + await expect(lock).toBeFocused() + await page.keyboard.press('Escape') + await expect(lock).toHaveAttribute('aria-pressed', 'false') + await expect(lock).toBeFocused() + expect(await page.evaluate(() => window.lockEvents)).toEqual([[true, true, true], [false, false, false]]) + await page.keyboard.press('Tab') + await expect(page.locator('.art-control-progress')).toBeFocused() +}) + +test('candidate: programmatic lock moves hidden control focus to unlock and caller tabindex survives', async ({ page }) => { + await setup(page) + await page.locator('.art-control-progress').focus() + await page.evaluate(() => { + window.art.controls.add({ name: 'custom', position: 'right', html: '' }) + window.art.plugins.lock.state = true + }) + await expect(page.locator('.art-layer-lock')).toBeFocused() + await expect(page.locator('.art-bottom')).toHaveAttribute('inert') + await expect(page.locator('.art-control-custom button')).toHaveAttribute('tabindex', '-1') + await page.keyboard.press('Enter') + await expect(page.locator('.art-bottom')).not.toHaveAttribute('inert') + await expect(page.locator('.art-control-custom button')).toHaveAttribute('tabindex', '3') +}) + +test('candidate: locked additions stay out of Tab order and removal or destruction releases focus attributes', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.plugins.lock.state = true + window.art.controls.add({ name: 'late', position: 'right', html: '' }) + }) + await expect(page.locator('.art-control-late button')).toHaveAttribute('tabindex', '-1') + await page.evaluate(() => { + window.retainedLock = window.art.layers.lock + window.art.layers.remove('lock') + }) + await expect(page.locator('.art-bottom')).not.toHaveAttribute('inert') + await expect(page.locator('.art-control-late button')).not.toHaveAttribute('tabindex') + await page.evaluate(() => { + window.lockEvents.length = 0 + window.retainedLock.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })) + window.art.destroy(false) + }) + expect(await page.evaluate(() => window.lockEvents)).toEqual([]) +}) + +test('candidate: lock Tab fallback works without native inert and preserves caller focus attributes', async ({ page }) => { + await setup(page) + await page.locator('.art-layer-lock').focus() + await page.keyboard.press('Enter') + await page.evaluate(() => window.art.template.$bottom.removeAttribute('inert')) + await page.keyboard.press('Tab') + await expect(page.locator('#play')).toBeFocused() + await page.keyboard.press('Shift+Tab') + await expect(page.locator('.art-layer-lock')).toBeFocused() + await page.keyboard.press('Escape') + await page.evaluate(() => { + window.art.template.$bottom.setAttribute('inert', 'caller-owned') + window.art.template.$bottom.setAttribute('aria-hidden', 'false') + window.art.plugins.lock.state = true + window.art.plugins.lock.state = false + }) + await expect(page.locator('.art-bottom')).toHaveAttribute('inert', 'caller-owned') + await expect(page.locator('.art-bottom')).toHaveAttribute('aria-hidden', 'false') +}) + +test('candidate: moving a control outside a locked region restores its tabindex and cleanup preserves later caller edits', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.controls.add({ name: 'borrowed', position: 'right', html: '' }) + window.art.plugins.lock.state = true + }) + await expect(page.locator('#borrowed-focus')).toHaveAttribute('tabindex', '-1') + await page.evaluate(() => document.body.append(document.querySelector('#borrowed-focus'))) + await expect(page.locator('#borrowed-focus')).toHaveAttribute('tabindex', '2') + await page.evaluate(() => { + window.art.controls.progress.setAttribute('tabindex', '4') + window.art.plugins.lock.state = false + }) + await expect(page.locator('.art-control-progress')).toHaveAttribute('tabindex', '4') +}) + +test('candidate: remounting an already locked layer reflects actual state and replaces its keyboard scope', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.plugins.lock.state = true + window.art.layers.update({ name: 'lock' }) + window.lockEvents.length = 0 + }) + const lock = page.locator('.art-layer-lock') + await expect(lock).toHaveAttribute('aria-pressed', 'true') + await expect(lock.locator('.art-icon-lock')).toBeVisible() + expect(await lock.locator('.art-icon-lock').evaluate(element => element.style.display)).toBe('inline-flex') + await expect(lock.locator('.art-icon-unlock')).toHaveCSS('display', 'none') + await lock.focus() + await page.keyboard.press('Space') + await expect(page.locator('.art-bottom')).not.toHaveAttribute('inert') + expect(await page.evaluate(() => window.lockEvents)).toEqual([[false, false, false]]) +}) diff --git a/test/browser/accessibility-mini.spec.js b/test/browser/accessibility-mini.spec.js new file mode 100644 index 000000000..f473c4b1b --- /dev/null +++ b/test/browser/accessibility-mini.spec.js @@ -0,0 +1,142 @@ +import { expect, test } from './fixtures.js' + +async function setup(page) { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => { + window.miniCalls = [] + const outside = document.createElement('button') + outside.id = 'mini-outside' + outside.textContent = 'Outside' + document.body.append(outside) + window.art = new window.Artplayer({ + container: '.player', + url: '/test/pattern.mp4', + muted: true, + hotkey: true, + controls: [{ name: 'mini-trigger', position: 'right', html: 'Mini', click() { this.mini = true } }], + }) + window.art.on('mini', value => window.miniCalls.push(['mini', value])) + window.art.on('play', () => window.miniCalls.push(['play'])) + window.art.on('pause', () => window.miniCalls.push(['pause'])) + window.art.on('hotkey', event => window.miniCalls.push(['hotkey', event.code])) + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +test('candidate: mini keyboard entry reaches close and stable playback controls and Escape returns focus', async ({ page }, testInfo) => { + await setup(page) + const trigger = page.locator('.art-control-mini-trigger') + await trigger.focus() + await page.keyboard.press('Enter') + const popup = page.locator('.art-mini-popup') + await expect(popup.locator('.art-mini-close')).toBeFocused() + await expect(popup.locator('.art-mini-close')).toHaveAttribute('aria-label', 'Close') + await page.keyboard.press('Tab') + await expect(popup.locator('.art-mini-state')).toBeFocused() + await expect(popup.locator('.art-mini-state')).toHaveAttribute('aria-label', 'Play') + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => window.art.playing)).toBe(true) + await expect(popup.locator('.art-mini-state')).toBeFocused() + await expect(popup.locator('.art-mini-state')).toHaveAttribute('aria-label', 'Pause') + await page.keyboard.press('Enter') + await expect.poll(() => page.evaluate(() => window.art.playing)).toBe(false) + await popup.screenshot({ path: testInfo.outputPath('mini-keyboard.png') }) + await page.keyboard.press('Escape') + await expect(popup).toBeHidden() + await expect(trigger).toBeFocused() + expect(await page.evaluate(() => window.miniCalls)).toEqual([['mini', true], ['play'], ['pause'], ['mini', false]]) +}) + +test('candidate: mini pointer entry preserves focus and Space closes after keyboard navigation', async ({ page }) => { + await setup(page) + await page.locator('#mini-outside').focus() + await page.locator('.art-control-mini-trigger').click() + await expect(page.locator('.art-mini-close')).not.toBeFocused() + await page.locator('.art-mini-close').focus() + await page.keyboard.press('Space') + await expect(page.locator('.art-mini-popup')).toBeHidden() + await expect(page.locator('.art-control-mini-trigger')).toBeFocused() + expect(await page.evaluate(() => window.miniCalls)).toEqual([['mini', true], ['mini', false]]) +}) + +test('candidate: programmatic mini exit preserves external focus and removed return targets use the player', async ({ page }) => { + await setup(page) + await page.locator('.art-control-mini-trigger').focus() + await page.keyboard.press('Enter') + await page.locator('#mini-outside').focus() + await page.evaluate(() => { + window.art.mini = false + }) + await expect(page.locator('#mini-outside')).toBeFocused() + await page.locator('.art-control-mini-trigger').focus() + await page.keyboard.press('Enter') + await page.evaluate(() => window.art.controls.remove('mini-trigger')) + await page.keyboard.press('Escape') + await expect(page.locator('.art-video-player')).toBeFocused() + await expect(page.locator('.art-mini-popup')).toBeHidden() +}) + +test('candidate: destroying from mini return focus cancels late notifications and retained controls', async ({ page }) => { + await setup(page) + await page.locator('.art-control-mini-trigger').focus() + await page.keyboard.press('Enter') + await page.evaluate(() => { + window.retainedMini = window.art.template.$mini + window.art.controls['mini-trigger'].addEventListener('focus', () => window.art.destroy(false), { once: true }) + window.miniCalls.length = 0 + }) + await page.keyboard.press('Escape') + expect(await page.evaluate(() => window.art.isDestroy)).toBe(true) + await page.evaluate(() => { + window.retainedMini.querySelector('.art-mini-close').click() + window.retainedMini.querySelector('.art-icon-play').click() + }) + expect(await page.evaluate(() => window.miniCalls)).toEqual([]) +}) + +test('candidate: mini reuse keeps keyboard entry and never returns to a stale or hidden origin', async ({ page }) => { + await setup(page) + const trigger = page.locator('.art-control-mini-trigger') + await trigger.focus() + await page.keyboard.press('Enter') + await page.keyboard.press('Escape') + await page.keyboard.press('Enter') + await expect(page.locator('.art-mini-close')).toBeFocused() + await page.evaluate(() => { + window.art.controls['mini-trigger'].style.visibility = 'hidden' + }) + await page.keyboard.press('Escape') + await expect(page.locator('.art-video-player')).toBeFocused() + await page.evaluate(() => { + window.art.controls['mini-trigger'].style.visibility = '' + }) + await page.locator('#mini-outside').focus() + await page.evaluate(() => { + window.art.mini = true + }) + await expect(page.locator('#mini-outside')).toBeFocused() + await page.locator('.art-mini-close').focus() + await page.keyboard.press('Escape') + await expect(page.locator('.art-video-player')).toBeFocused() +}) + +test('candidate: mini names use existing i18n keys and hidden controls cannot reactivate the mode', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + const get = window.art.i18n.get.bind(window.art.i18n) + const names = { 'Close': 'Localized close', 'Play': 'Localized play', 'Pause': 'Localized pause', 'Mini Player': 'Localized mini' } + window.art.i18n.get = key => names[key] || get(key) + }) + await page.locator('.art-control-mini-trigger').focus() + await page.keyboard.press('Enter') + await expect(page.locator('.art-mini-popup')).toHaveAttribute('aria-label', 'Localized mini') + await expect(page.locator('.art-mini-close')).toHaveAttribute('aria-label', 'Localized close') + await expect(page.locator('.art-mini-state')).toHaveAttribute('aria-label', 'Localized play') + await page.keyboard.press('Escape') + await page.evaluate(() => { + window.miniCalls.length = 0 + for (const selector of ['.art-mini-close', '.art-mini-state']) + document.querySelector(selector).dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })) + }) + expect(await page.evaluate(() => window.miniCalls)).toEqual([]) +}) diff --git a/test/browser/accessibility-selector.spec.js b/test/browser/accessibility-selector.spec.js new file mode 100644 index 000000000..6fd68494b --- /dev/null +++ b/test/browser/accessibility-selector.spec.js @@ -0,0 +1,252 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, mode = 'normal') { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate((mode) => { + window.selectorCalls = [] + window.selectorClicks = [] + window.selectorHotkeys = [] + window.pendingSelections = {} + window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, hotkey: true, fullscreenWeb: true }) + window.art.on('hotkey', event => window.selectorHotkeys.push(event.code)) + const selector = mode === 'empty' + ? [] + : mode === 'complex' + ? [{ html: '', value: 'native' }, { html: '', value: 'input' }] + : ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', 'Hotel'].map((html, index) => ({ html, value: html, default: index === 1 })) + window.art.controls.add({ name: 'keyboard-selector', position: 'right', html: 'Bravo', tooltip: 'Quality', selector, click(component, event) { + window.selectorClicks.push([this === window.art, component === this.controls, event.type]) + }, onSelect(item, element, event) { + window.selectorCalls.push([this === window.art, item.value, element === item.$control_item, event.type]) + if (mode === 'async') + return new Promise(resolve => window.pendingSelections[item.value] = resolve) + if (mode === 'external-focus') + document.querySelector('#play').focus() + return item.html + } }) + }, mode) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +const trigger = page => page.locator('.art-control-keyboard-selector .art-selector-value') +const list = page => page.locator('.art-control-keyboard-selector .art-selector-list') +const item = (page, index) => list(page).locator('.art-selector-item').nth(index) + +test('candidate: selector Tab entry, focus navigation and typeahead do not commit before Enter', async ({ page }, testInfo) => { + await setup(page) + await page.locator('.art-control-playAndPause').focus() + for (let attempt = 0; attempt < 8 && !await trigger(page).evaluate(element => document.activeElement === element); attempt++) + await page.keyboard.press('Tab') + await expect(trigger(page)).toBeFocused() + await expect(trigger(page)).toHaveAttribute('aria-haspopup', 'listbox') + await expect(trigger(page)).toHaveAttribute('aria-expanded', 'false') + await expect(list(page)).toHaveAttribute('role', 'listbox') + await expect(list(page)).toHaveAttribute('aria-label', 'Quality') + await expect(list(page)).toBeHidden() + await page.keyboard.press('ArrowDown') + await expect(item(page, 1)).toBeFocused() + await expect(item(page, 1)).toHaveAttribute('aria-selected', 'true') + await page.keyboard.press('ArrowDown') + await expect(item(page, 2)).toBeFocused() + await expect(item(page, 2)).toHaveAttribute('aria-selected', 'false') + await page.keyboard.press('f') + await expect(item(page, 5)).toBeFocused() + await page.keyboard.press('Home') + await expect(item(page, 0)).toBeFocused() + await page.keyboard.press('End') + await expect(item(page, 7)).toBeFocused() + expect(await page.evaluate(() => window.selectorCalls)).toEqual([]) + expect(await page.evaluate(() => window.art.currentTime)).toBe(0) + expect(await page.evaluate(() => window.art.volume)).toBe(0.7) + await page.locator('.player').screenshot({ path: testInfo.outputPath('selector-keyboard.png') }) + await page.keyboard.press('Enter') + await expect(trigger(page)).toBeFocused() + await expect(trigger(page)).toHaveText('Hotel') + await expect(trigger(page)).toHaveAttribute('aria-expanded', 'false') + await expect(list(page)).toBeHidden() + await expect(item(page, 7)).toHaveAttribute('aria-selected', 'true') + await expect(item(page, 1)).toHaveAttribute('aria-selected', 'false') + expect(await page.evaluate(() => window.selectorCalls)).toEqual([[true, 'Hotel', true, 'click']]) + expect(await page.evaluate(() => window.selectorHotkeys)).toEqual([]) + expect(await page.locator('.art-control-keyboard-selector').getAttribute('role')).toBeNull() +}) + +test('candidate: selector Space commits once and Escape closes before web fullscreen exits', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.fullscreenWeb = true + }) + await trigger(page).focus() + await page.keyboard.down('Space') + await page.keyboard.down('Space') + await expect(list(page)).toBeHidden() + await page.keyboard.up('Space') + await expect(item(page, 1)).toBeFocused() + await page.keyboard.press('ArrowDown') + await page.keyboard.down('Space') + await page.keyboard.down('Space') + expect(await page.evaluate(() => window.selectorCalls)).toEqual([]) + await page.keyboard.up('Space') + await expect(trigger(page)).toBeFocused() + expect(await page.evaluate(() => window.selectorCalls)).toEqual([[true, 'Charlie', true, 'click']]) + expect(await page.evaluate(() => window.selectorClicks)).toEqual([[true, true, 'click'], [true, true, 'click']]) + await page.keyboard.press('ArrowDown') + await expect(item(page, 2)).toBeFocused() + await page.keyboard.press('Escape') + await expect(trigger(page)).toBeFocused() + await expect(list(page)).toBeHidden() + expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(true) + expect(await page.evaluate(() => window.selectorHotkeys)).toEqual([]) + await page.keyboard.press('Tab') + await expect(trigger(page)).not.toBeFocused() + await expect(list(page)).toBeHidden() +}) + +test('candidate: keyboard selector retains asynchronous choice ownership and disposal', async ({ page }) => { + await setup(page, 'async') + await trigger(page).focus() + await page.keyboard.press('ArrowDown') + await page.keyboard.press('Home') + await page.keyboard.press('Enter') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('End') + await page.keyboard.press('Enter') + await page.evaluate(() => { + window.pendingSelections.Hotel('Latest') + window.pendingSelections.Alpha('Obsolete') + }) + await expect(trigger(page)).toHaveText('Latest') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('Home') + await page.keyboard.press('Enter') + await page.evaluate(() => { + window.detachedValue = window.art.controls['keyboard-selector'].querySelector('.art-selector-value') + window.art.controls.remove('keyboard-selector') + window.pendingSelections.Alpha('After removal') + }) + expect(await page.evaluate(() => window.detachedValue.textContent)).toBe('Alpha') + expect(await page.evaluate(() => { + const event = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true, cancelable: true }) + window.detachedValue.dispatchEvent(event) + return event.defaultPrevented + })).toBe(false) +}) + +test('candidate: pointer hover and selector selection retain their existing click behavior', async ({ page }) => { + await setup(page) + await page.locator('#play').focus() + await trigger(page).hover() + await expect(list(page)).toBeVisible() + await expect(trigger(page)).toHaveAttribute('aria-expanded', 'true') + await item(page, 0).click() + await expect(trigger(page)).toHaveText('Alpha') + await expect(item(page, 0)).toHaveAttribute('aria-selected', 'true') + expect(await page.evaluate(() => window.selectorCalls)).toEqual([[true, 'Alpha', true, 'click']]) + await trigger(page).focus() + await page.keyboard.press('ArrowDown') + await page.keyboard.press('Escape') + await expect(list(page)).toBeHidden() + await page.locator('#play').hover() + await trigger(page).hover() + await expect(list(page)).toBeVisible() + await expect(trigger(page)).toHaveAttribute('aria-expanded', 'true') +}) + +test('candidate: custom native controls retain their semantics and typing inside selector content', async ({ page }) => { + await setup(page, 'complex') + await trigger(page).focus() + await page.keyboard.press('ArrowDown') + await expect(page.locator('#nested-option')).toBeFocused() + await expect(list(page)).toHaveAttribute('role', 'group') + expect(await item(page, 0).getAttribute('role')).toBeNull() + await page.keyboard.press('Space') + expect(await page.evaluate(() => window.selectorCalls)).toEqual([[true, 'native', true, 'click']]) + const currentButton = trigger(page).locator('#nested-option') + await expect(currentButton).toBeFocused() + expect(await trigger(page).getAttribute('role')).toBeNull() + expect(await currentButton.getAttribute('aria-haspopup')).toBeNull() + expect(await page.evaluate(() => window.art.video.paused)).toBe(true) + await page.keyboard.press('ArrowDown') + await expect(list(page).locator('#nested-option')).toBeFocused() + await page.locator('.art-selector-list #nested-input').focus() + await page.keyboard.press('End') + await page.keyboard.type(' text') + await expect(page.locator('.art-selector-list #nested-input')).toHaveValue('Editable text') + await page.keyboard.press('Escape') + await expect(list(page)).toBeHidden() + expect(await page.evaluate(() => window.selectorHotkeys)).toEqual([]) +}) + +test('candidate: empty selectors are disabled and selection callbacks keep explicitly moved focus', async ({ page }) => { + await setup(page, 'empty') + await trigger(page).focus() + await expect(trigger(page)).toHaveAttribute('aria-disabled', 'true') + await page.keyboard.press('ArrowDown') + await page.keyboard.press('Enter') + await expect(trigger(page)).toHaveAttribute('aria-expanded', 'false') + await expect(trigger(page)).toBeFocused() + expect(await page.evaluate(() => window.selectorClicks)).toEqual([]) + await setup(page, 'external-focus') + await trigger(page).focus() + await page.keyboard.press('ArrowDown') + await page.keyboard.press('Enter') + await expect(page.locator('#play')).toBeFocused() + await expect(list(page)).toBeHidden() +}) + +test('candidate: typeahead accepts prefixes, resets after navigation and leaves modified input alone', async ({ page }) => { + await setup(page) + await trigger(page).focus() + await page.keyboard.press('ArrowDown') + await page.keyboard.type('ho') + await expect(item(page, 7)).toBeFocused() + await page.keyboard.press('Home') + await page.keyboard.press('f') + await expect(item(page, 5)).toBeFocused() + await page.keyboard.press('ArrowUp') + await page.keyboard.press('h') + await expect(item(page, 7)).toBeFocused() + await page.keyboard.press('Control+Home') + await expect(item(page, 7)).toBeFocused() + expect(await page.evaluate(() => window.selectorCalls)).toEqual([]) +}) + +test('candidate: native trigger markup remains a single button and can open the existing popup', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.controls.update({ name: 'keyboard-selector', html: '' }) + }) + const button = page.locator('#custom-trigger') + await expect(button).toHaveAttribute('aria-haspopup', 'listbox') + expect(await trigger(page).getAttribute('role')).toBeNull() + await button.focus() + await page.keyboard.press('Space') + await expect(item(page, 1)).toBeFocused() + expect(await page.evaluate(() => window.selectorClicks)).toEqual([[true, true, 'click']]) + expect(await page.evaluate(() => window.art.video.paused)).toBe(true) + await page.keyboard.press('Escape') + await expect(button).toBeFocused() + await expect(list(page)).toBeHidden() +}) + +test('candidate: a dismissed hovered selector releases the next Escape to fullscreen', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.fullscreenWeb = true + }) + await trigger(page).hover() + await trigger(page).focus() + await page.keyboard.press('ArrowDown') + await page.keyboard.press('Escape') + await expect(list(page)).toBeHidden() + expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(true) + await page.keyboard.press('Escape') + await expect.poll(() => page.evaluate(() => window.art.fullscreenWeb)).toBe(false) +}) + +test('candidate: hovering an empty selector does not announce an expanded popup', async ({ page }) => { + await setup(page, 'empty') + await trigger(page).hover() + await expect(trigger(page)).toHaveAttribute('aria-expanded', 'false') + await expect(trigger(page)).toHaveAttribute('aria-disabled', 'true') +}) diff --git a/test/browser/accessibility-setting.spec.js b/test/browser/accessibility-setting.spec.js new file mode 100644 index 000000000..80515b087 --- /dev/null +++ b/test/browser/accessibility-setting.spec.js @@ -0,0 +1,269 @@ +import { expect, test } from './fixtures.js' + +async function setup(page) { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => { + window.settingCalls = [] + window.settingHotkeys = [] + window.art = new window.Artplayer({ + container: '.player', + url: '/test/pattern.mp4', + muted: true, + hotkey: true, + setting: true, + fullscreenWeb: true, + playbackRate: false, + aspectRatio: false, + flip: false, + subtitleOffset: false, + settings: [ + { name: 'quality', html: 'Quality', tooltip: 'Auto', selector: [ + { name: 'auto', html: 'Auto', default: true }, + { name: 'hd', html: 'HD' }, + { name: 'more', html: 'More', selector: [{ name: 'ultra', html: 'Ultra' }, { name: 'cinema', html: 'Cinema' }] }, + ], onSelect(item, element, event) { + window.settingCalls.push(['select', item.name, this === window.art, element === item.$item, event.type]) + return item.html + } }, + { name: 'loop', html: 'Loop', switch: false, onSwitch(item, element, event) { + window.settingCalls.push(['switch', this === window.art, element === item.$item, event.type]) + return !item.switch + } }, + { name: 'offset', html: 'Offset', range: [0, -10, 10, 1], onChange(item, element, event) { + window.settingCalls.push(['input', item.range[0], this === window.art, element === item.$item, event.type]) + return `${item.range[0]}s` + }, onRange(item, element, event) { + window.settingCalls.push(['change', item.range[0], this === window.art, element === item.$item, event.type]) + return `${item.range[0]}s` + } }, + { name: 'action', html: 'Action', onClick(item, element, event) { + window.settingCalls.push(['action', this === window.art, element === item.$item, event.type]) + return 'Clicked' + } }, + ], + }) + window.art.on('hotkey', event => window.settingHotkeys.push(event.code)) + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.locator('.art-control-setting').focus() +} + +const row = (page, name) => page.locator(`.art-setting-item[data-name="${name}"]`) +const button = page => page.locator('.art-control-setting') + +for (const unavailable of ['removed', 'hidden', 'disabled']) { + test(`candidate: setting exit falls back to the player when its button is ${unavailable}`, async ({ page }) => { + await setup(page) + await page.keyboard.press('Enter') + await expect(row(page, 'quality')).toBeFocused() + await page.evaluate((unavailable) => { + if (unavailable === 'removed') + window.art.controls.remove('setting') + else if (unavailable === 'hidden') + window.art.controls.setting.style.visibility = 'hidden' + else + window.art.controls.setting.setAttribute('aria-disabled', 'true') + }, unavailable) + await page.keyboard.press('Escape') + await expect(page.locator('.art-settings')).toHaveCount(1) + await expect(page.locator('.art-settings')).toBeHidden() + await expect(page.locator('.art-video-player')).toBeFocused() + }) +} + +test('candidate: setting navigation ignores hidden rows and inert descendants', async ({ page }) => { + await setup(page) + await page.keyboard.press('Enter') + await page.evaluate(() => { + window.art.setting.find('loop').$item.style.visibility = 'hidden' + window.art.setting.find('offset').$item.setAttribute('inert', '') + }) + await page.keyboard.press('ArrowDown') + await expect(row(page, 'action')).toBeFocused() + await page.keyboard.press('ArrowUp') + await expect(row(page, 'quality')).toBeFocused() +}) + +test('candidate: setting keyboard enters nested panels and returns to the originating item', async ({ page }, testInfo) => { + await setup(page) + await page.evaluate(() => { + window.art.fullscreenWeb = true + }) + await expect(button(page)).toBeFocused() + await page.keyboard.press('Enter') + await expect(row(page, 'quality')).toBeFocused() + await expect(button(page)).toHaveAttribute('aria-expanded', 'true') + await expect(page.locator('.art-setting-panel.art-current')).toHaveAttribute('aria-label', 'Settings') + await page.keyboard.press('ArrowRight') + await expect(row(page, 'auto')).toBeFocused() + await expect(row(page, 'auto')).toHaveAttribute('aria-current', 'true') + await page.keyboard.press('ArrowDown') + await expect(row(page, 'hd')).toBeFocused() + expect(await page.evaluate(() => window.settingCalls)).toEqual([]) + await page.keyboard.press('Enter') + await expect(row(page, 'quality')).toBeFocused() + expect(await page.evaluate(() => window.settingCalls)).toEqual([['select', 'hd', true, true, 'click']]) + await expect(row(page, 'quality')).toContainText('HD') + await page.keyboard.press('ArrowRight') + await expect(row(page, 'hd')).toBeFocused() + await expect(row(page, 'hd')).toHaveAttribute('aria-current', 'true') + await page.keyboard.press('End') + await expect(row(page, 'more')).toBeFocused() + await page.keyboard.press('ArrowRight') + await expect(row(page, 'ultra')).toBeFocused() + await page.keyboard.press('ArrowLeft') + await expect(row(page, 'more')).toBeFocused() + await page.keyboard.press('Home') + await expect(page.locator('.art-setting-panel.art-current .art-setting-item-back')).toBeFocused() + await expect(page.locator('.art-setting-panel.art-current .art-setting-item-back')).toHaveAttribute('aria-label', 'Back: Quality') + await page.keyboard.press('Space') + await expect(row(page, 'quality')).toBeFocused() + await page.locator('.art-video-player').screenshot({ path: testInfo.outputPath('setting-keyboard.png') }) + await page.keyboard.press('Escape') + await expect(button(page)).toBeFocused() + await expect(button(page)).toHaveAttribute('aria-expanded', 'false') + expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(true) + expect(await page.evaluate(() => window.settingHotkeys)).toEqual([]) + await page.keyboard.press('Escape') + await expect.poll(() => page.evaluate(() => window.art.fullscreenWeb)).toBe(false) +}) + +test('candidate: setting switches and native ranges keep callbacks and avoid player shortcuts', async ({ page }) => { + await setup(page) + await page.keyboard.press('ArrowDown') + await page.keyboard.press('ArrowDown') + await expect(row(page, 'loop')).toBeFocused() + await expect(row(page, 'loop')).toHaveAttribute('role', 'switch') + await expect(row(page, 'loop')).toHaveAttribute('aria-checked', 'false') + await page.keyboard.down('Space') + await page.keyboard.down('Space') + await page.keyboard.up('Space') + await expect(row(page, 'loop')).toHaveAttribute('aria-checked', 'true') + expect(await page.evaluate(() => window.settingCalls)).toEqual([['switch', true, true, 'click']]) + await page.keyboard.press('Tab') + const range = row(page, 'offset').locator('input') + await expect(range).toBeFocused() + await expect(range).toHaveAttribute('aria-label', 'Offset') + await page.keyboard.press('ArrowRight') + await expect(range).toHaveValue('1') + await expect.poll(() => page.evaluate(() => window.settingCalls.filter(item => ['input', 'change'].includes(item[0])))).toEqual([ + ['input', 1, true, true, 'input'], + ['change', 1, true, true, 'change'], + ]) + await page.evaluate(() => { + window.art.setting.find('offset').html = 'Subtitle delay' + }) + await expect(range).toHaveAttribute('aria-label', 'Subtitle delay') + expect(await page.evaluate(() => [window.art.currentTime, window.art.volume, window.art.video.paused])).toEqual([0, 0.7, true]) + expect(await page.evaluate(() => window.settingHotkeys)).toEqual([]) + await page.keyboard.press('Escape') + await expect(button(page)).toBeFocused() +}) + +test('candidate: setting Tab leaves without trapping focus and pointer opening keeps its old focus path', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.settingFocusOrder = [] + window.art.template.$setting.addEventListener('focusin', event => window.settingFocusOrder.push(event.target.dataset.name)) + }) + await page.keyboard.press('ArrowUp') + await expect(row(page, 'action')).toBeFocused() + expect(await page.evaluate(() => window.settingFocusOrder)).toEqual(['action']) + await page.keyboard.press('Tab') + await expect.poll(() => page.evaluate(() => window.art.setting.show)).toBe(false) + await expect(row(page, 'action')).not.toBeFocused() + await button(page).click() + await expect.poll(() => page.evaluate(() => window.art.setting.show)).toBe(true) + await expect(row(page, 'quality')).not.toBeFocused() + await row(page, 'action').click() + expect(await page.evaluate(() => window.settingCalls)).toEqual([['action', true, true, 'click']]) +}) + +test('candidate: setting update, failed replacement and removal recover visible focus', async ({ page }) => { + await setup(page) + await page.keyboard.press('ArrowUp') + await expect(row(page, 'action')).toBeFocused() + await page.evaluate(() => window.art.setting.update({ name: 'action', html: 'Updated' })) + await expect(row(page, 'action')).toBeFocused() + await expect(row(page, 'action')).toHaveText('Updated') + await page.evaluate(() => { + const setting = window.art.setting + const create = setting.createItem + setting.createItem = function (...args) { + create.apply(this, args) + throw new Error('forced keyboard replacement failure') + } + try { + setting.update({ name: 'action', html: 'Failed' }) + } + catch (error) { + window.settingUpdateFailure = error.message + } + finally { + setting.createItem = create + } + }) + expect(await page.evaluate(() => window.settingUpdateFailure)).toBe('forced keyboard replacement failure') + await expect(row(page, 'action')).toBeFocused() + await expect(row(page, 'action')).toHaveText('Updated') + await page.keyboard.press('Enter') + expect(await page.evaluate(() => window.settingCalls)).toEqual([['action', true, true, 'click']]) + await page.evaluate(() => window.art.setting.remove('action')) + await expect(row(page, 'quality')).toBeFocused() +}) + +test('candidate: suspended settings ignore keyboard callbacks and restored items resume', async ({ page }) => { + await setup(page) + await page.keyboard.press('ArrowUp') + await page.evaluate(() => { + const target = { name: 'action' } + Object.defineProperty(target, 'html', { enumerable: true, get() { + const item = window.art.setting.find('action').$item + item.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })) + item.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true, cancelable: true })) + throw new Error('resume old keyboard item') + } }) + try { + window.art.setting.update(target) + } + catch {} + }) + expect(await page.evaluate(() => window.settingCalls)).toEqual([]) + expect(await page.evaluate(() => window.art.currentTime)).toBe(0) + await expect(row(page, 'action')).toBeFocused() + await page.keyboard.press('Enter') + expect(await page.evaluate(() => window.settingCalls)).toEqual([['action', true, true, 'click']]) +}) + +test('candidate: native setting buttons retain their role, click path and keyboard navigation', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.art.setting.add({ name: 'native', html: '', onClick(item, element, event) { + window.settingCalls.push(['native', this === window.art, element === item.$item, event.type]) + return 'Done' + } }) + }) + await page.keyboard.press('ArrowUp') + const native = page.locator('#native-setting') + await expect(native).toBeFocused() + expect(await row(page, 'native').getAttribute('role')).toBeNull() + await page.keyboard.press('Space') + expect(await page.evaluate(() => window.settingCalls)).toEqual([['native', true, true, 'click']]) + expect(await page.evaluate(() => window.art.video.paused)).toBe(true) + await page.keyboard.press('ArrowUp') + await expect(row(page, 'action')).toBeFocused() + expect(await page.evaluate(() => window.settingHotkeys)).toEqual([]) +}) + +test('candidate: destroying during moved focus restoration cancels fullscreen notifications', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + window.modeEvents = [] + window.art.on('fullscreenWeb', value => window.modeEvents.push(['fullscreenWeb', value])) + window.art.on('resize', () => window.modeEvents.push(['resize'])) + window.art.controls.setting.addEventListener('focus', () => window.art.destroy(false), { once: true }) + window.art.fullscreenWeb = true + }) + expect(await page.evaluate(() => window.art.isDestroy)).toBe(true) + expect(await page.evaluate(() => window.modeEvents)).toEqual([]) +}) diff --git a/test/browser/accessibility-slider.spec.js b/test/browser/accessibility-slider.spec.js new file mode 100644 index 000000000..887e2a969 --- /dev/null +++ b/test/browser/accessibility-slider.spec.js @@ -0,0 +1,155 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, options = {}) { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate((options) => { + const before = document.createElement('button') + before.id = 'before-player' + before.textContent = 'Before player' + document.body.prepend(before) + window.Artplayer.SEEK_STEP = 0.5 + window.Artplayer.VOLUME_STEP = 0.05 + window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, hotkey: true, ...options }) + window.sliderEvents = [] + window.art.on('hotkey', event => window.sliderEvents.push(['hotkey', event.code])) + window.art.on('seek', (actual, value) => window.sliderEvents.push(['seek', value])) + window.art.on('setBar', (kind, ratio, event) => { + if (kind === 'played') + window.sliderEvents.push(['setBar', ratio, event?.type ?? null]) + }) + }, options) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.locator('#before-player').focus() + await page.keyboard.press('Tab') + if (await page.locator('.art-video').evaluate(element => element.ownerDocument.activeElement === element)) + await page.keyboard.press('Tab') + await expect(page.locator('.art-control-progress')).toBeFocused() +} + +test('candidate: progress is the first control, seeks with owned keys and follows actual media time', async ({ page }) => { + await setup(page) + const slider = page.locator('.art-control-progress') + await expect(slider).toHaveAttribute('role', 'slider') + await expect(slider).toHaveAttribute('aria-label', 'Progress') + await expect(slider).toHaveAttribute('aria-disabled', 'false') + await page.evaluate(() => { + window.art.currentTime = 1 + }) + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeCloseTo(1, 1) + await expect.poll(() => page.evaluate(() => window.art.video.seeking)).toBe(false) + await expect.poll(() => page.evaluate(() => Math.abs(Number(document.querySelector('.art-control-progress').getAttribute('aria-valuenow')) - window.art.currentTime))).toBeLessThan(0.001) + const start = await page.evaluate(() => window.art.currentTime) + await page.evaluate(() => { + window.sliderEvents.length = 0 + }) + await page.keyboard.press('ArrowRight') + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeCloseTo(start + 0.5, 1) + await expect.poll(() => page.evaluate(() => Math.abs(Number(document.querySelector('.art-control-progress').getAttribute('aria-valuenow')) - window.art.currentTime))).toBeLessThan(0.001) + const events = await page.evaluate(() => window.sliderEvents) + expect(events.slice(0, 2)).toEqual([['setBar', (start + 0.5) / await page.evaluate(() => window.art.duration), null], ['seek', start + 0.5]]) + await page.keyboard.press('ArrowUp') + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeCloseTo(2, 1) + expect(await page.evaluate(() => window.art.volume)).toBe(0.7) + await page.keyboard.press('Home') + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeCloseTo(0, 1) + await page.keyboard.press('End') + await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - window.art.duration))).toBeLessThan(0.1) + await page.keyboard.press('PageDown') + try { + await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - Math.max(0, window.art.duration - 5)))).toBeLessThan(0.1) + } + finally { + await test.info().attach('slider-after-pagedown', { contentType: 'application/json', body: JSON.stringify(await page.evaluate(() => ({ + events: window.sliderEvents, + focus: document.activeElement?.className, + currentTime: window.art.currentTime, + duration: window.art.duration, + seeking: window.art.video.seeking, + ended: window.art.video.ended, + paused: window.art.video.paused, + }))) }) + } + expect(await page.evaluate(() => window.sliderEvents.filter(event => event[0] === 'hotkey'))).toEqual([]) + await expect(slider).toBeFocused() + await page.keyboard.press('Tab') + await expect(page.locator('.art-control-playAndPause')).toBeFocused() +}) + +test('candidate: volume panel opens from keyboard focus and the slider unmutes without seeking', async ({ page }) => { + await setup(page) + await page.keyboard.press('Tab') + await page.keyboard.press('Tab') + await expect(page.locator('.art-icon-volumeClose')).toBeFocused() + const slider = page.locator('.art-volume-slider') + await expect(slider).toBeVisible() + await expect.poll(() => page.locator('.art-volume-panel').evaluate(element => getComputedStyle(element).opacity)).toBe('1') + await page.keyboard.press('Tab') + await expect(slider).toBeFocused() + await expect(slider).toHaveAttribute('aria-label', 'Volume') + await expect(slider).toHaveAttribute('aria-orientation', 'vertical') + await expect(slider).toHaveAttribute('aria-valuenow', '0') + await page.keyboard.press('ArrowUp') + await expect.poll(() => page.evaluate(() => window.art.volume)).toBeCloseTo(0.05, 5) + expect(await page.evaluate(() => window.art.muted)).toBe(false) + await expect(slider).toHaveAttribute('aria-valuetext', '5%') + await page.keyboard.press('PageUp') + await expect.poll(() => page.evaluate(() => window.art.volume)).toBeCloseTo(0.55, 5) + await page.keyboard.press('End') + await expect.poll(() => page.evaluate(() => window.art.volume)).toBe(1) + await page.keyboard.press('Home') + await expect.poll(() => page.evaluate(() => window.art.volume)).toBe(0) + expect(await page.evaluate(() => window.art.currentTime)).toBe(0) + expect(await page.evaluate(() => window.sliderEvents.filter(event => ['seek', 'hotkey'].includes(event[0])))).toEqual([]) + await expect(slider).toBeFocused() + await page.locator('#before-player').focus() + await expect.poll(() => page.locator('.art-volume-panel').evaluate(element => getComputedStyle(element).visibility)).toBe('hidden') +}) + +test('candidate: unknown duration disables progress until metadata returns and labels use i18n', async ({ page }) => { + await setup(page, { lang: 'zh-cn' }) + const slider = page.locator('.art-control-progress') + await expect(slider).toHaveAttribute('aria-label', '播放进度') + await page.evaluate(() => { + Object.defineProperty(window.art.video, 'duration', { configurable: true, value: Infinity }) + window.art.video.dispatchEvent(new Event('durationchange')) + window.sliderEvents.length = 0 + }) + await expect(slider).toHaveAttribute('aria-disabled', 'true') + await expect(slider).toHaveAttribute('aria-valuemax', '0') + await page.keyboard.press('End') + await page.keyboard.press('ArrowRight') + expect(await page.evaluate(() => window.sliderEvents)).toEqual([]) + await page.evaluate(() => { + delete window.art.video.duration + window.art.video.dispatchEvent(new Event('durationchange')) + }) + await expect(slider).toHaveAttribute('aria-disabled', 'false') + await page.keyboard.press('ArrowRight') + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeCloseTo(0.5, 1) +}) + +test('candidate: progress removal and volume destruction inside callbacks cancel pending writes', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + const remove = (kind, ratio) => { + if (kind === 'played' && ratio > 0) { + window.art.off('setBar', remove) + window.art.controls.remove('progress') + } + } + window.art.on('setBar', remove) + window.sliderEvents.length = 0 + }) + await page.keyboard.press('ArrowRight') + expect(await page.evaluate(() => window.art.currentTime)).toBe(0) + expect(await page.evaluate(() => window.sliderEvents.filter(event => event[0] === 'seek'))).toEqual([]) + await page.locator('.art-icon-volumeClose').focus() + await page.keyboard.press('Tab') + await expect(page.locator('.art-volume-slider')).toBeFocused() + await page.evaluate(() => { + window.savedVideo = window.art.video + window.art.once('muted', () => window.art.destroy(false)) + }) + await page.keyboard.press('ArrowUp') + expect(await page.evaluate(() => window.savedVideo.volume)).toBe(0.7) +}) diff --git a/test/browser/accessibility.spec.js b/test/browser/accessibility.spec.js new file mode 100644 index 000000000..d9f54dc04 --- /dev/null +++ b/test/browser/accessibility.spec.js @@ -0,0 +1,161 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core = 'candidate') { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(() => { + const before = document.createElement('button') + before.id = 'before-player' + before.textContent = 'Before player' + document.body.prepend(before) + window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, hotkey: true, setting: true, fullscreenWeb: true, screenshot: true }) + window.keyboardHits = [] + window.art.on('hotkey', event => window.keyboardHits.push(event.code)) + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.locator('#before-player').focus() +} + +async function tabPastNativeVideo(page) { + await page.keyboard.press('Tab') + // Firefox includes the native video in its existing sequential focus order. + if (await page.locator('.art-video').evaluate(element => element.ownerDocument.activeElement === element)) + await page.keyboard.press('Tab') +} + +async function tabToPlay(page) { + await tabPastNativeVideo(page) + await expect(page.locator('.art-control-progress')).toBeFocused() + await page.keyboard.press('Tab') +} + +test('published: Tab skips the non-interactive main controls', async ({ page }) => { + await setup(page, 'published') + await tabPastNativeVideo(page) + await expect(page.locator('#play')).toBeFocused() + expect(await page.locator('.art-controls [tabindex="0"]').count()).toBe(0) +}) + +test('candidate: keyboard reaches stable play control and toggles once with focus retained', async ({ page }) => { + await setup(page) + await tabToPlay(page) + const play = page.locator('.art-control-playAndPause') + await expect(play).toBeFocused() + await expect(play).toHaveAttribute('role', 'button') + await expect(play).toHaveAttribute('aria-label', 'Play') + await page.keyboard.press('Enter') + await expect.poll(() => page.evaluate(() => window.art.playing && window.art.currentTime > 0.1)).toBe(true) + await expect(play).toBeFocused() + await expect(play).toHaveAttribute('aria-label', 'Pause') + await page.keyboard.down('Space') + expect(await page.evaluate(() => window.art.playing)).toBe(true) + await page.keyboard.up('Space') + await expect.poll(() => page.evaluate(() => window.art.video.paused)).toBe(true) + await expect(play).toBeFocused() + expect(await page.evaluate(() => window.keyboardHits)).toEqual([]) + await page.keyboard.press('Tab') + await expect(page.locator('.art-control-volume .art-icon-volumeClose')).toBeFocused() +}) + +test('candidate: mute state, focus visibility and automatic hiding follow keyboard focus', async ({ page }) => { + await setup(page) + await tabToPlay(page) + await page.keyboard.press('Enter') + await expect.poll(() => page.evaluate(() => window.art.playing)).toBe(true) + await page.evaluate(() => { + window.Artplayer.CONTROL_HIDE_TIME = 0 + }) + await page.keyboard.press('Tab') + const muted = page.locator('.art-control-volume .art-icon-volumeClose') + const audible = page.locator('.art-control-volume .art-icon-volume') + await expect(muted).toBeFocused() + await expect(muted).toHaveAttribute('aria-label', 'Mute') + await expect(muted).toHaveAttribute('aria-pressed', 'true') + await page.keyboard.press('Space') + await expect(audible).toBeFocused() + await expect(audible).toHaveAttribute('aria-pressed', 'false') + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.5) + expect(await page.evaluate(() => window.art.controls.show)).toBe(true) + expect(await audible.evaluate(element => getComputedStyle(element).outlineStyle)).not.toBe('none') + expect(await page.evaluate(() => window.keyboardHits)).toEqual([]) + await page.locator('#before-player').focus() + await expect.poll(() => page.evaluate(() => window.art.controls.show)).toBe(false) + expect(await page.evaluate(() => window.art.isFocus)).toBe(false) +}) + +test('candidate: custom control keyboard clicks retain the callback and release on replacement', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + const art = window.art + window.customHits = [] + art.controls.add({ name: 'keyboard-custom', position: 'right', html: 'Custom', click(component, event) { + window.customHits.push({ same: this === art, component: component === art.controls, type: event.type }) + } }) + }) + const control = page.locator('.art-control-keyboard-custom') + await control.focus() + await page.keyboard.press('Enter') + await page.keyboard.down('Space') + await page.keyboard.down('Space') + await page.keyboard.up('Space') + expect(await page.evaluate(() => window.customHits)).toEqual([ + { same: true, component: true, type: 'click' }, + { same: true, component: true, type: 'click' }, + ]) + await page.keyboard.down('Space') + await page.evaluate(() => { + const art = window.art + window.oldControl = art.controls['keyboard-custom'] + art.controls.update({ name: 'keyboard-custom', html: 'Replaced' }) + }) + await page.keyboard.up('Space') + await page.evaluate(() => { + window.oldControl.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })) + }) + expect(await page.evaluate(() => window.customHits.length)).toBe(2) + await control.focus() + await page.keyboard.press('Enter') + expect(await page.evaluate(() => window.customHits.length)).toBe(3) + await page.evaluate(() => window.art.destroy(false)) + expect(await page.evaluate(() => { + window.oldControl.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })) + return window.customHits.length + })).toBe(3) +}) + +test('candidate: native buttons inside custom controls retain activation without player hotkeys', async ({ page }) => { + await setup(page) + await page.evaluate(() => { + const art = window.art + window.nativeButtonHits = 0 + window.parentButtonHits = 0 + const button = document.createElement('button') + button.textContent = 'Native action' + button.addEventListener('click', () => window.nativeButtonHits++) + art.controls.add({ name: 'native-action', position: 'right', html: button, click() { + window.parentButtonHits++ + } }) + art.hotkey.add('KeyK', () => window.keyboardHits.push('custom-k')) + }) + const parent = page.locator('.art-control-native-action') + const button = parent.locator('button') + await expect(parent).not.toHaveAttribute('role', 'button') + await button.focus() + await page.keyboard.press('Space') + await page.keyboard.press('Enter') + expect(await page.evaluate(() => ({ native: window.nativeButtonHits, parent: window.parentButtonHits, paused: window.art.video.paused, hotkeys: window.keyboardHits }))).toEqual({ native: 2, parent: 2, paused: true, hotkeys: [] }) + await page.keyboard.press('k') + expect(await page.evaluate(() => window.keyboardHits)).toEqual(['custom-k', 'KeyK']) +}) + +test('candidate: pointer focus does not prevent the existing automatic control hiding', async ({ page }) => { + await setup(page) + // Start a pointer interaction after setup's programmatic focus. + await page.locator('.art-control-playAndPause .art-icon-play').click() + await expect.poll(() => page.evaluate(() => window.art.playing)).toBe(true) + await page.evaluate(() => { + window.Artplayer.CONTROL_HIDE_TIME = 0 + }) + await page.mouse.move(900, 650) + await expect.poll(() => page.evaluate(() => window.art.controls.show)).toBe(false) + await expect.poll(() => page.locator('.art-bottom').evaluate(element => getComputedStyle(element).opacity)).toBe('0') +}) diff --git a/test/builtin-layers.test.js b/test/builtin-layers.test.js index 42a819d88..07ee53b69 100644 --- a/test/builtin-layers.test.js +++ b/test/builtin-layers.test.js @@ -14,7 +14,15 @@ const { lock, miniProgressBar, Emitter, beginLifecycle, getScope, ownEntry, rele }) function fixture(t) { - class Element { + class Element extends EventTarget { + ownerDocument = { activeElement: null } + attributes = new Map() + setAttribute(key, value) { this.attributes.set(key, String(value)) } + getAttribute(key) { return this.attributes.get(key) ?? null } + hasAttribute(key) { return this.attributes.has(key) } + removeAttribute(key) { this.attributes.delete(key) } + contains(node) { return node === this || this.children.some(child => child.contains(node)) } + querySelectorAll() { return this.children } style = {} children = [] appendChild(child) { @@ -30,7 +38,8 @@ function fixture(t) { const element = new Element() let option const art = Object.assign(new Emitter(), { - template: { $player: { classList } }, + template: { $player: { classList }, $bottom: new Element() }, + i18n: { get: key => key }, isLock: false, icons: { lock: new Element(), unlock: new Element() }, layers: { add(value) { diff --git a/test/prompt-components.test.js b/test/prompt-components.test.js index be0c07fbe..8ed4e3d54 100644 --- a/test/prompt-components.test.js +++ b/test/prompt-components.test.js @@ -14,7 +14,14 @@ const { Info, Loading, Mask, Emitter, beginLifecycle, getScope, destroyInstance }) function fixture(t) { - class Element { + const document = { activeElement: null, body: null } + class Element extends EventTarget { + ownerDocument = document + attributes = new Map() + setAttribute(key, value) { this.attributes.set(key, String(value)) } + getAttribute(key) { return this.attributes.get(key) } + hasAttribute(key) { return this.attributes.has(key) } + contains(node) { return node === this || this.children.some(child => child.contains(node)) } style = {} children = [] textContent = '' @@ -51,7 +58,8 @@ function fixture(t) { const listeners = new Set() const art = Object.assign(new Emitter(), { constructor: { INFO_LOOP_TIME: 100 }, - template: { $player: player, $infoPanel: panel, $infoClose: new Element(), $video: { currentTime: 1.234, src: 'first' }, $loading: new Element(), $state: new Element() }, + template: { $player: player, $info: new Element(), $infoPanel: panel, $infoClose: new Element(), $video: { currentTime: 1.234, src: 'first' }, $loading: new Element(), $state: new Element() }, + i18n: { get: key => key }, icons: { loading: new Element(), state: new Element(), error: new Element() }, play: () => Promise.resolve(), })