From a842058136997b94db93155dc6db06eab72604bb Mon Sep 17 00:00:00 2001 From: Harvey Zhao Date: Fri, 11 Sep 2026 11:24:15 +0800 Subject: [PATCH] refactor(core): CORE-17 type input events and own interaction lifetimes --- docs/compiled/artplayer.js | 2 +- docs/compiled/artplayer.legacy.js | 2 +- docs/compiled/artplayer.mjs | 933 +- package.json | 2 +- packages/artplayer/ARCHITECTURE.md | 126 + packages/artplayer/dist/artplayer.js | 2 +- packages/artplayer/dist/artplayer.legacy.js | 2 +- packages/artplayer/dist/artplayer.mjs | 933 +- .../src/control/progress/position.ts | 19 +- packages/artplayer/src/events/clickInit.js | 65 - packages/artplayer/src/events/clickInit.ts | 45 + packages/artplayer/src/events/gestureInit.js | 104 - packages/artplayer/src/events/gestureInit.ts | 19 + packages/artplayer/src/events/global-types.ts | 17 + packages/artplayer/src/events/globalInit.js | 52 - packages/artplayer/src/events/globalInit.ts | 80 + packages/artplayer/src/events/hoverInit.js | 17 - packages/artplayer/src/events/hoverInit.ts | 22 + packages/artplayer/src/events/index.js | 80 - packages/artplayer/src/events/index.ts | 59 + .../artplayer/src/events/listener-registry.ts | 135 + packages/artplayer/src/events/moveInit.js | 7 - packages/artplayer/src/events/moveInit.ts | 10 + packages/artplayer/src/events/resizeInit.js | 29 - packages/artplayer/src/events/resizeInit.ts | 35 + .../artplayer/src/events/scheduling-types.ts | 34 + .../artplayer/src/events/subscriptions.ts | 17 + packages/artplayer/src/events/types.ts | 6 + packages/artplayer/src/events/updateInit.js | 23 - packages/artplayer/src/events/updateInit.ts | 21 + packages/artplayer/src/events/viewInit.js | 21 - packages/artplayer/src/events/viewInit.ts | 29 + packages/artplayer/src/events/viewport.ts | 11 + packages/artplayer/src/hotkey.js | 96 - packages/artplayer/src/hotkey.ts | 94 + .../artplayer/src/input/gesture-controller.ts | 94 + .../artplayer/src/input/gesture-direction.ts | 16 + packages/artplayer/src/input/gesture-types.ts | 26 + .../artplayer/src/input/hotkey-defaults.ts | 27 + packages/artplayer/src/input/hotkey-types.ts | 16 + .../artplayer/src/input/keyboard-focus.ts | 30 + packages/artplayer/src/input/pointer-focus.ts | 21 + packages/artplayer/src/input/pointer-types.ts | 39 + packages/artplayer/types/events.d.ts | 1 + refactor/baselines/gesture-validation.json | 2218 ++ refactor/baselines/hotkey-validation.json | 2430 ++ .../baselines/input-listeners-validation.json | 1168 + refactor/baselines/input-validation.json | 19176 ++++++++++++++++ refactor/baselines/pointer-validation.json | 1428 ++ refactor/changes/2026-09-11-CORE-17-input.md | 88 + refactor/core-design.md | 2 +- refactor/plan.md | 5 +- refactor/progress.md | 8 + refactor/risk-table.md | 11 + refactor/risks.json | 225 + refactor/tasks.json | 7 +- test/browser/event-scheduling.spec.js | 125 + test/browser/gesture.spec.js | 150 + test/browser/global-events.spec.js | 99 + test/browser/hotkey.spec.js | 214 + test/browser/input-closeout.spec.js | 175 + test/browser/listener-registry.spec.js | 151 + test/browser/pointer-events.spec.js | 112 + test/event-scheduling.test.js | 223 + test/gesture.test.js | 215 + test/global-events.test.js | 133 + test/hotkey.test.js | 168 + test/listener-registry.test.js | 201 + test/pointer-events.test.js | 161 + test/types/events-source.ts | 29 + test/types/gesture.ts | 16 + test/types/hotkey.ts | 18 + 72 files changed, 31156 insertions(+), 1219 deletions(-) delete mode 100644 packages/artplayer/src/events/clickInit.js create mode 100644 packages/artplayer/src/events/clickInit.ts delete mode 100644 packages/artplayer/src/events/gestureInit.js create mode 100644 packages/artplayer/src/events/gestureInit.ts create mode 100644 packages/artplayer/src/events/global-types.ts delete mode 100644 packages/artplayer/src/events/globalInit.js create mode 100644 packages/artplayer/src/events/globalInit.ts delete mode 100644 packages/artplayer/src/events/hoverInit.js create mode 100644 packages/artplayer/src/events/hoverInit.ts delete mode 100644 packages/artplayer/src/events/index.js create mode 100644 packages/artplayer/src/events/index.ts create mode 100644 packages/artplayer/src/events/listener-registry.ts delete mode 100644 packages/artplayer/src/events/moveInit.js create mode 100644 packages/artplayer/src/events/moveInit.ts delete mode 100644 packages/artplayer/src/events/resizeInit.js create mode 100644 packages/artplayer/src/events/resizeInit.ts create mode 100644 packages/artplayer/src/events/scheduling-types.ts create mode 100644 packages/artplayer/src/events/subscriptions.ts create mode 100644 packages/artplayer/src/events/types.ts delete mode 100644 packages/artplayer/src/events/updateInit.js create mode 100644 packages/artplayer/src/events/updateInit.ts delete mode 100644 packages/artplayer/src/events/viewInit.js create mode 100644 packages/artplayer/src/events/viewInit.ts create mode 100644 packages/artplayer/src/events/viewport.ts delete mode 100644 packages/artplayer/src/hotkey.js create mode 100644 packages/artplayer/src/hotkey.ts create mode 100644 packages/artplayer/src/input/gesture-controller.ts create mode 100644 packages/artplayer/src/input/gesture-direction.ts create mode 100644 packages/artplayer/src/input/gesture-types.ts create mode 100644 packages/artplayer/src/input/hotkey-defaults.ts create mode 100644 packages/artplayer/src/input/hotkey-types.ts create mode 100644 packages/artplayer/src/input/keyboard-focus.ts create mode 100644 packages/artplayer/src/input/pointer-focus.ts create mode 100644 packages/artplayer/src/input/pointer-types.ts create mode 100644 refactor/baselines/gesture-validation.json create mode 100644 refactor/baselines/hotkey-validation.json create mode 100644 refactor/baselines/input-listeners-validation.json create mode 100644 refactor/baselines/input-validation.json create mode 100644 refactor/baselines/pointer-validation.json create mode 100644 refactor/changes/2026-09-11-CORE-17-input.md create mode 100644 test/browser/event-scheduling.spec.js create mode 100644 test/browser/gesture.spec.js create mode 100644 test/browser/global-events.spec.js create mode 100644 test/browser/hotkey.spec.js create mode 100644 test/browser/input-closeout.spec.js create mode 100644 test/browser/listener-registry.spec.js create mode 100644 test/browser/pointer-events.spec.js create mode 100644 test/event-scheduling.test.js create mode 100644 test/gesture.test.js create mode 100644 test/global-events.test.js create mode 100644 test/hotkey.test.js create mode 100644 test/listener-registry.test.js create mode 100644 test/pointer-events.test.js create mode 100644 test/types/events-source.ts create mode 100644 test/types/gesture.ts create mode 100644 test/types/hotkey.ts diff --git a/docs/compiled/artplayer.js b/docs/compiled/artplayer.js index cded353cc..e64148bcc 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{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new l,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 s?t.push(...e.errors):t.push(e)}if(t.length)throw new s(t)}}const c=new WeakMap,d=new WeakMap;function p(t){const e=c.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function u(t){return p(t).scope}function h(t){const e=p(t);return e.destroying||e.scope.closed}function f(t,e,r,n,o=!1){const a=p(t);if(a.destroying||a.scope.closed)return;a.destroying=!0;const i=[],l=t=>{try{t()}catch(e){i.push(...e instanceof s?e.errors:[e])}};n&&t.template?.$video&&l(()=>t.reset()),l(()=>a.scope.dispose()),l(()=>t.template?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(a.releaseContainer?.(),a.releaseContainer=void 0),l(()=>t.emit("destroy")),o&&a.rollback&&l(a.rollback),a.rollback=void 0,a.releaseContainer?.(),a.releaseContainer=void 0;for(const s of i.slice(1))console.warn("Additional ArtPlayer cleanup failure:",s);if(i.length)throw i[0]}const m=new WeakMap;function g(t,e){const r=u(t).child();return m.set(e,r),r}function v(t){const e=m.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function y(t){m.get(t)?.dispose()}function b(t,e){return{on:(r,n)=>{!function(t,e,r,n){const o=v(e);if(o.closed)return;const a=(...t)=>{if(!o.closed)return n(...t)};t.on(r,a),o.add(()=>{t.off(r,a)})}(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const a=v(e);if(a.closed)return()=>{};const i=t.events.proxy(r,n,t=>{if(!a.closed)return o(t)});return a.add(()=>{t.events.remove(i)})}(t,e,r,n,o)}}const w=globalThis?.CUSTOM_USER_AGENT??("undefined"!==typeof navigator?navigator.userAgent:""),x=/^(?:(?!chrome|android).)*safari/i.test(w),k=/iPad|iPhone|iPod/i.test(w)&&!window.MSStream,$=k||w.includes("Macintosh")&&navigator.maxTouchPoints>=1,E=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(w)||$,T="undefined"!==typeof window&&"undefined"!==typeof document;function C(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function L(t,e=document){return e.querySelector(t)}function S(t,e=document){return Array.from(e.querySelectorAll(t))}function P(t,e){return t.classList.add(e)}function M(t,e){return t.classList.remove(e)}function z(t,e){return t.classList.contains(e)}function A(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function R(t,e,r){return t.style[e]=r,t}function O(t,e){for(const r in e)R(t,r,e[r]);return t}function I(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function _(t,e){I(t).forEach(t=>M(t,e)),P(t,e)}function N(t,e,r="top"){E||(t.setAttribute("aria-label",e),P(t,"hint--rounded"),P(t,`hint--${r}`))}function D(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,a=r.top-e<=n&&r.top+r.height+e>=0,i=r.left-e<=o+e&&r.left+r.width+e>=0;return a&&i}function W(t,e){return q(t).includes(e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function V(t){return document.createElement(t)}function Y(t="",e=""){const r=V("i");return P(r,"art-icon"),P(r,`art-icon-${t}`),A(r,e),r}function B(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function H(t){return t.getBoundingClientRect()}function j(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const a=document.createElement("canvas"),i=a.getContext("2d");a.width=o.width*e,a.height=o.height*e,i.drawImage(o,0,0,a.width,a.height),a.toBlob(e=>{const o=URL.createObjectURL(e),a=new Image;a.onload=function(){r(a)},a.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},a.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function q(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function U(){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;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class X extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function G(t,e){if(!t)throw new X(e);return t}function K(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function Z(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function J(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 Q(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function tt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function et(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 rt={"&":"&","<":"<",">":">","'":"'",'"':"""},nt={"&":"&","<":"<",">":">","'":"'",""":'"'},ot=/(&|<|>|'|")/g;function at(t){return t.replace(/[&<>'"]/g,t=>rt[t]||t)}const it=Object.defineProperty,{hasOwnProperty:st}=Object.prototype;function lt(t,e){return st.call(t,e)}function ct(t,e){return Object.getOwnPropertyDescriptor(t,e)}function dt(...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],a=r[n];let i;i=Array.isArray(o)&&Array.isArray(a)?o.concat(...a):e(o)&&e(a)?dt(o,a):a,it(t,n,{value:i,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function pt(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 ht(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="",a="",,,i=""]=n;return{start:r(o.trim()),end:r(a.trim()),text:i.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")}`}function ft(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}}const mt=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:X,addClass:P,append:A,assToVtt:ht,capitalize:tt,clamp:Q,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:J,errorHandle:G,escape:at,get:ct,getComposedPath:q,getExt:Z,getIcon:Y,getRect:H,getSafeAreaInsets:U,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:lt,hasClass:z,includeFromEvent:W,inverseClass:_,isBrowser:T,isIOS:k,isIOS13:$,isInViewport:D,isMobile:E,isSafari:x,loadImg:j,mergeDeep:dt,query:L,queryAll:S,remove:function(t){return t.parentNode.removeChild(t)},removeClass:M,replaceElement:F,secondToTime:et,setStyle:R,setStyleText:C,setStyles:O,siblings:I,silencePromise:K,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:pt,supportsFlex:B,throttle:ft,tooltip:N,unescape:function(t){return t.replace(ot,t=>nt[t]||t)},userAgent:w,vttToBlob:ut},Symbol.toStringTag,{value:"Module"}));function gt(t,e){return A(t,e)}function vt(t,e){return e.querySelector(t)}const yt="array",bt="boolean",wt="string",xt="number",kt="object",$t="function";function Et(t,e,r){return G(e===wt||e===xt||t instanceof Element,`${r.join(".")} require '${wt}' or 'Element' type`)}const Tt={html:Et,disable:`?${bt}`,name:`?${wt}`,index:`?${xt}`,style:`?${kt}`,click:`?${$t}`,mounted:`?${$t}`,tooltip:`?${wt}|${xt}`,width:`?${xt}`,selector:`?${yt}`,onSelect:`?${$t}`,switch:`?${bt}`,onSwitch:`?${$t}`,range:`?${yt}`,onRange:`?${$t}`,onChange:`?${$t}`},Ct={id:wt,container:Et,url:wt,poster:wt,type:wt,theme:wt,lang:wt,volume:xt,isLive:bt,muted:bt,autoplay:bt,autoSize:bt,autoMini:bt,loop:bt,flip:bt,playbackRate:bt,aspectRatio:bt,screenshot:bt,setting:bt,hotkey:bt,pip:bt,mutex:bt,backdrop:bt,fullscreen:bt,fullscreenWeb:bt,subtitleOffset:bt,miniProgressBar:bt,useSSR:bt,playsInline:bt,lock:bt,gesture:bt,fastForward:bt,autoPlayback:bt,autoOrientation:bt,airplay:bt,proxy:`?${$t}`,plugins:[$t],layers:[Tt],contextmenu:[Tt],settings:[Tt],controls:[{...Tt,position:(t,e,r)=>{const n=["top","left","right"];return G("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${bt}`,html:wt,url:wt}],highlight:[{time:xt,text:wt}],thumbnails:{url:wt,number:xt,column:xt,width:xt,height:xt,scale:xt},subtitle:{url:wt,name:wt,type:wt,style:kt,escape:bt,encoding:wt,onVttLoad:$t},moreVideoAttr:kt,i18n:kt,icons:kt,cssVar:kt,customType:kt},Lt=new WeakSet;class St{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 z(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?P(e,r):M(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t;if(h(this.art))return;if(e.html=e.html||"",o(e,Tt),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;G(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const a=document.createElement("div"),i=g(this.art,a),s=[],l=Object.getOwnPropertyDescriptor(this,r);let c=!1;i.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(i.closed)return;if(function(t,e,r,n,o,a){P(t,`art-${r}`),P(t,`art-${r}-${n}`);const i=Array.from(e.children);t.dataset.index=String(a.index||o);const s=i.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):A(e,t),a.html&&A(t,a.html),a.style&&O(t,a.style),a.tooltip&&N(t,a.tooltip)}(a,this.$parent,this.name,r,this.id,e),i.closed)return;if(e.click){const t=this.art.events.proxy(a,"click",t=>{i.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,a,s),i.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,a),c=!0,n.set(r,{$ref:a,events:s,option:e}),e.mounted&&e.mounted.call(this.art,a),a}catch(d){try{y(a)}catch(p){console.warn("ArtPlayer component cleanup failed:",p)}throw n.get(r)?.$ref===a&&n.delete(r),c&&this[r]===a&&(l?Object.defineProperty(this,r,l):delete this[r]),a.remove(),d}}remove(t){G(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Lt.has(e)){Lt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{y(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Lt.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 Pt extends St{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,g(t,this.$parent),E||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=b(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}=b(e,t),n=L('[data-value="1"]',t);n&&_(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&_(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}=b(e,t),n=L('[data-value="default"]',t);n&&_(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(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(tt(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}=b(e,t),n=L('[data-value="normal"]',t);n&&_(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(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 ${a}`}}({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 a=0;a{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:a,width:i,left:s,top:l}=H(e),{height:c,width:d}=H(r);let p=n-s,u=o-l;n+d>s+i&&(p=i-d),o+c>l+a&&(u=a-c),O(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{W(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Mt(t,e,r,n,o={}){const{capture:a=!1,once:i=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let l=()=>{};function c(e){i&&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,a)}finally{s?.removeEventListener("abort",l)}}),s?.addEventListener("abort",l,{once:!0}),l}function zt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const a=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(a)}),o}function At(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const a=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(a),n||r(!1)})})}function Rt(t,e){const{$progress:r}=t.template,{left:n}=H(r),o=Q((E?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),a=o/r.clientWidth*t.duration;return{second:a,time:et(a),width:o,percentage:Q(o/r.clientWidth,0,1)}}function Ot(t,e){if(t.isRotate){const r=(e.touches[0].clientY-t.top)/t.height,n=r*t.duration;t.emit("setBar","played",r,e),t.seek=n}else{const{second:r,percentage:n}=Rt(t,e);t.emit("setBar","played",n,e),t.seek=r}}function It(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,a=v(e),{on:i}=b(t,e);let s=()=>{};const l=vt(".art-progress-hover",e),c=vt(".art-progress-loaded",e),d=vt(".art-progress-played",e),p=vt(".art-progress-highlight",e),u=vt(".art-progress-indicator",e),h=vt(".art-progress-tip",e);function f(r,n){const{width:o,time:a}=n||Rt(t,r);h.textContent=a||"00:00";const i=h.clientWidth;o<=i/2?R(h,"left",0):o>e.clientWidth-i/2?R(h,"left",e.clientWidth-i+"px"):R(h,"left",o-i/2+"px")}r.indicator?A(u,r.indicator):R(u,"backgroundColor","var(--art-theme)"),i("setBar",function(r,n,i){const m="played"===r&&i&&E;if("loaded"===r&&R(c,"width",100*n+"%"),"hover"===r&&(R(l,"width",100*n+"%"),W(i,p)?function(r){const{width:n}=Rt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const a=h.clientWidth;n<=a/2?R(h,"left",0):n>e.clientWidth-a/2?R(h,"left",e.clientWidth-a+"px"):R(h,"left",n-a/2+"px")}(i):f(i),0===n?M(o,"art-progress-hover"):P(o,"art-progress-hover")),"played"===r&&(R(d,"width",100*n+"%"),R(u,"left",100*n+"%")),m){P(o,"art-progress-hover");f(i,{width:e.clientWidth*n,time:et(n*t.duration)}),s(),s=zt(a,()=>{M(o,"art-progress-hover")},500)}}),i("video:loadedmetadata",function(){p.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(i("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),i("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),i("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function _t(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{It(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:a}=b(t,e);if(!E){let e=!1;a(r,"click",e=>{e.target!==n&&Ot(t,e)}),a(r,"mousemove",e=>{const{percentage:r}=Rt(t,e);t.emit("setBar","hover",r,e)}),a(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),a(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=Rt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function Nt(t){const{option:e}=t.art;e.isLive||t.add(_t({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}=b(e,t),{icons:o,i18n:a}=e,i=gt(t,o.play),s=gt(t,o.pause);function l(){R(i,"display","flex"),R(s,"display","none")}function c(){R(i,"display","none"),R(s,"display","flex")}N(i,a.get("Play")),N(s,a.get("Pause")),n(i,"click",()=>{K(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}=b(e,t),{icons:o}=e,a=gt(t,o.volume),i=gt(t,o.volumeClose),s=gt(t,'
'),l=gt(s,'
'),c=gt(l,'
'),d=gt(l,'
'),p=gt(d,'
'),u=gt(p,'
'),h=gt(d,'
');function f(t){const{top:e,height:r}=H(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)R(a,"display","none"),R(i,"display","flex"),R(h,"top","100%"),R(u,"top","100%"),c.textContent="0";else{const t=100*e.volume;R(a,"display","flex"),R(i,"display","none"),R(h,"top",100-t+"%"),R(u,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(a,"click",()=>{e.muted=!0}),n(i,"click",()=>{e.muted=!1}),E)R(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=>({...t,style:E?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=b(e,t);function n(){const r=`${et(e.currentTime)} / ${et(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!u(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!E&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=b(e,t),{icons:n}=e;gt(t,n.screenshot),r(t,"click",()=>{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}=b(e,t),{icons:o,i18n:a}=e;gt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{N(t,a.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}=b(e,t),{icons:o,i18n:a}=e;gt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{N(t,a.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}=b(e,t),{icons:n}=e;gt(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}=b(e,t),{icons:o,i18n:a}=e,i=gt(t,o.fullscreenWebOn),s=gt(t,o.fullscreenWebOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(N(t,a.get("Exit Web Fullscreen")),R(i,"display","none"),R(s,"display","inline-flex")):(N(t,a.get("Web Fullscreen")),R(i,"display","inline-flex"),R(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}=b(e,t),{icons:o,i18n:a}=e,i=gt(t,o.fullscreenOn),s=gt(t,o.fullscreenOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(N(t,a.get("Exit Fullscreen")),R(i,"display","none"),R(s,"display","inline-flex")):(N(t,a.get("Fullscreen")),R(i,"display","inline-flex"),R(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rWt.get(t).option.selector}),it(t,"$control_item",{get:()=>Wt.get(t).item}),it(t,"$control_value",{get:()=>Wt.get(t).value})),Wt.set(t,e)}function Vt(t,e){t.innerHTML=e}function Yt(t,e,r,n,o){const{proxy:a}=t.events,i=v(n),s=r.selector;P(n,"art-control-selector");const l=document.createElement("div");P(l,"art-selector-value"),A(l,r.html),n.textContent="",A(n,l);const c=gt(n,'
');for(let u=0;u{if(i.closed)return;const o=q(n),a=r.selector.find(t=>o.includes(t.$control_item));if(!a)return;const s=++d,c=()=>!i.closed&&s===d,p=i.add(function(t,e){return Dt.set(t,e),()=>{Dt.get(t)===e&&Dt.delete(t)}}(n,c));try{if(e(a),i.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,a,a.$control_item,n);c()&&Vt(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Bt extends St{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;g(t,n);const{on:o}=b(t,n);o("mousemove",()=>{E||(this.show=!0)}),o("click",()=>{E?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=W(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?(M(r,"art-hide-cursor"),P(r,"art-hover"),this.timer=Date.now()):(P(r,"art-hide-cursor"),M(r,"art-hover"))}),this.init(),u(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=v(e),{on:a}=b(t,e),i=()=>{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(a("resize",i),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(i);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(i);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}i()}(t)}init(){Nt(this)}add(t){if(h(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:G(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Vt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Ht(t,e,r,n){const o=e-n,a=r-t;let i=0;if(Math.abs(a)<2&&Math.abs(o)<2)return i;const s=function(t,e){return 180*Math.atan2(e,t)/Math.PI}(a,o);return s>=-45&&s<45?i=4:s>=45&&s<135?i=1:s>=-135&&s<-45?i=2:(s>=135&&s<=180||s>=-180&&s<-135)&&(i=3),i}function jt(t){if(t.constructor.USE_RAF){const e=u(t);let r=()=>{};!function n(){t.playing&&t.emit("raf"),t.isDestroy||(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))}(),t.on("destroy",()=>{r()})}}const qt=new WeakMap;class Ut{constructor(t){this.destroyEvents=new Set;const e=u(t);qt.set(this,e),e.add(()=>this.destroy()),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),function(t,e){const{constructor:r,template:{$player:n,$video:o}}=t;function a(e){W(e,n)?(t.isInput="INPUT"===e.target.tagName,t.isFocus=!0,t.emit("focus",e)):(t.isInput=!1,t.isFocus=!1,t.emit("blur",e))}t.on("document:click",a),t.on("document:contextmenu",a);let i=[];e.proxy(o,"click",e=>{const n=Date.now();i.push(n);const{MOBILE_CLICK_PLAY:o,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=i.filter(t=>n-t<=a);switch(c.length){case 1:t.emit("click",e),E?!t.isLock&&o&&K(t.toggle()):K(t.toggle()),i=c;break;case 2:t.emit("dblclick",e),E?!t.isLock&&s&&K(t.toggle()):l&&(t.fullscreen=!t.fullscreen),i=[];break;default:i=[]}})}(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{P(r,"art-hover"),t.emit("hover",!0,e)},e=>{M(r,"art-hover"),t.emit("hover",!1,e)})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t;t.on("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),t.aspectRatio=e,n.show=""});const o=u(t);let a=()=>{};const i=()=>{a(),a=zt(o,()=>t.emit("resize"),n.RESIZE_TIME)};t.on("window:orientationchange",()=>i()),t.on("window:resize",()=>i()),screen&&screen.orientation&&screen.orientation.onchange&&e.proxy(screen.orientation,"change",()=>i())}(t,this),function(t,e){if(E&&!t.option.isLive){const{$video:r,$progress:n}=t.template;let o=null,a=!1,i=0,s=0,l=0;const c=e=>{if(1===e.touches.length&&!t.isLock){o===n&&Ot(t,e),a=!0;const{pageX:r,pageY:c}=e.touches[0];i=r,s=c,l=t.currentTime}},d=e=>{if(1===e.touches.length&&a&&t.duration){const{pageX:n,pageY:a}=e.touches[0],c=Ht(i,s,n,a),d=[3,4].includes(c),p=[1,2].includes(c);if(d&&!t.isRotate||p&&t.isRotate){const c=Q((n-i)/t.width,-1,1),d=Q((a-s)/t.height,-1,1),p=t.isRotate?d:c,u=o===r?t.constructor.TOUCH_MOVE_RATIO:1,h=Q(l+t.duration*p*u,0,t.duration);t.seek=h,t.emit("setBar","played",Q(h/t.duration,0,1),e),t.notice.show=`${et(h)} / ${et(t.duration)}`}}},p=()=>{a&&(i=0,s=0,l=0,a=!1,o=null)};t.option.gesture&&(e.proxy(r,"touchstart",t=>{o=r,c(t)}),e.proxy(r,"touchmove",d)),e.proxy(n,"touchstart",t=>{o=n,c(t)}),e.proxy(n,"touchmove",d),t.on("document:touchend",p)}}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=ft(()=>{t.emit("view",D(n,r.SCROLL_GAP))},r.SCROLL_TIME);t.on("window:scroll",()=>o()),t.on("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){const r=["click","mouseup","keydown","touchend","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],n=["resize","scroll","orientationchange"],o=[];function a(a={}){for(let t=0;t{const n=a.document||i.ownerDocument||document,s=e.proxy(n,r,e=>{t.emit(`document:${r}`,e)});o.push(s)}),n.forEach(r=>{const n=a.window||i.ownerDocument?.defaultView||window,s=e.proxy(n,r,e=>{t.emit(`window:${r}`,e)});o.push(s)})}a(),e.bindGlobalEvents=a}(t,this),jt(t)}proxy(t,e,r,n={}){if(Array.isArray(e))return e.map(e=>this.proxy(t,e,r,n));if(qt.get(this).closed)return()=>{};t.addEventListener(e,r,n);const o=()=>t.removeEventListener(e,r,n);return this.destroyEvents.add(o),o}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){if(this.destroyEvents.has(t))try{t()}catch(e){console.warn("Failed to remove event listener:",e)}finally{this.destroyEvents.delete(t)}}destroy(){for(const e of this.destroyEvents)try{e()}catch(t){console.warn("Failed to destroy event listener:",t)}this.destroyEvents.clear()}}class Xt{constructor(t){this.art=t,this.keys={},E||this.init()}init(){const{constructor:t}=this.art;this.art.option.hotkey&&(this.add("Escape",()=>{this.art.fullscreenWeb&&(this.art.fullscreenWeb=!1)}),this.add("Space",()=>{K(this.art.toggle())}),this.add("ArrowLeft",()=>{this.art.backward=t.SEEK_STEP}),this.add("ArrowUp",()=>{this.art.volume+=t.VOLUME_STEP}),this.add("ArrowRight",()=>{this.art.forward=t.SEEK_STEP}),this.add("ArrowDown",()=>{this.art.volume-=t.VOLUME_STEP})),this.art.on("document:keydown",t=>{if(this.art.isFocus){const e=document.activeElement.tagName.toUpperCase(),r=document.activeElement.getAttribute("contenteditable");if("INPUT"!==e&&"TEXTAREA"!==e&&""!==r&&"true"!==r&&!t.altKey&&!t.ctrlKey&&!t.metaKey&&!t.shiftKey){const e=this.keys[t.code];if(e){t.preventDefault();for(let r=0;r\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 Jt{constructor(t){const e={...Zt,...t.option.icons};for(const r in e)it(this,r,{get:()=>Y(r,e[r])})}}class Qt extends St{constructor(t){super(t),this.name="info",E||this.init()}init(){const{proxy:t,constructor:e,template:{$infoPanel:r,$infoClose:n,$video:o}}=this.art;t(n,"click",()=>{this.show=!1});let a=()=>{};const i=S("[data-video]",r)||[];this.art.on("destroy",()=>a());const s=u(this.art);!function t(){for(let e=0;e{R(o,"display","none"),R(a,"display",null)}),n.proxy(e.$state,"click",()=>K(t.play()))}}class ne{constructor(t){this.art=t,this.timer=null,u(t).add(()=>this.destroy()),t.on("destroy",()=>this.destroy())}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}set show(t){if(u(this.art).closed)return;const{constructor:e,template:{$player:r,$noticeInner:n}}=this.art;t?(n.textContent=t instanceof Error?t.message.trim():t,P(r,"art-notice-show"),clearTimeout(this.timer),this.timer=setTimeout(()=>{n.textContent="",M(r,"art-notice-show")},e.NOTICE_TIME)):M(r,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function oe({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function ae(t,e){if(!oe(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 oe(r)?r:void 0}function ie(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(h(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!oe(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||h(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function se(t,e,r,n=!1){const o=e=>{h(t)||r(e)};t[n?"once":"on"](e,o),u(t).add(()=>{t.off(e,o)})}function le(t,e,r){for(const[n,o]of e){if(h(t)||r&&!r())return;t[n].show=o}}const ce=new WeakMap,de=new WeakMap,pe=new WeakMap;function ue(t){return pe.get(t)||u(t)}function he(t){const e=ce.get(t),r=pe.get(t);return()=>ce.get(t)===e&&(!e||e.active())&&pe.get(t)===r&&(!r||!r.closed)}function fe(t){const e=pe.get(t),r=u(t).child(),n=r.child();pe.set(t,r),r.add(()=>{pe.get(t)===r&&pe.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!h(t)&&!n.closed&&ce.get(t)===o};return ce.set(t,o),n.add(()=>{ce.get(t)===o&&ce.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function me(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function ge(t,e,r){de.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{de.get(t)===e&&(de.delete(t),me(e))}}function ve(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function ye(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:a}}=t;let i,s=ue(t),l=0;return{reset(){l=0,i?.dispose(),M(a,"art-error")},loadStart(){M(a,"art-error")},schedule(c){(async c=>{if(h(t))return;const d=ue(t);if(d!==s&&(s=d,l=0),i&&!i.closed)return;const p=d.child();i=p,p.add(()=>{i===p&&(i=void 0)});const u=()=>!h(t)&&!p.closed&&d===ue(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function be(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{h(t)||t.emit(`video:${e.type}`,e)})}(t);const e=ye(t);!function(t,e){se(t,"video:canplay",()=>{e.reset(),le(t,[["loading",!1]])}),se(t,"video:canplay",()=>{le(t,[["loading",!1],["controls",!0],["mask",!0]]),h(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=he(t);if(t.seek=0,h(t)||!e())return;K(t.play()),e()&&le(t,[["controls",!1],["mask",!1]],e)}else le(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"),E&&le(t,[["loading",!1],["controls",!0],["mask",!0]])}),se(t,"video:loadstart",()=>{e.loadStart(),le(t,[["loading",!0],["mask",!1],["controls",!0]])}),se(t,"video:pause",()=>{le(t,[["controls",!0],["mask",!0]])}),se(t,"video:play",()=>{le(t,[["mask",!1]]),h(t)||R(r,"display","none")}),se(t,"video:playing",()=>le(t,[["mask",!1]])),se(t,"video:progress",()=>{t.playing&&le(t,[["loading",!1]])}),se(t,"video:seeked",()=>le(t,[["loading",!1],["mask",!0]])),se(t,"video:seeking",()=>le(t,[["loading",!0],["mask",!1]])),se(t,"video:timeupdate",()=>le(t,[["mask",!1]])),se(t,"video:waiting",()=>le(t,[["loading",!0],["mask",!1]]))}(t,e)}const we=[["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"]],xe=(()=>{if("undefined"===typeof document)return!1;const t=we[0],e={};for(const r of we){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),ke={change:xe.fullscreenchange,error:xe.fullscreenerror},$e={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{$e.off("change",o),r()};$e.on("change",o);const a=t[xe.requestFullscreen](e);a instanceof Promise&&a.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!$e.isFullscreen)return void t();const r=()=>{$e.off("change",r),t()};$e.on("change",r);const n=document[xe.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>$e.isFullscreen?$e.exit():$e.request(t,e),onchange(t){$e.on("change",t)},onerror(t){$e.on("error",t)},on(t,e){const r=ke[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=ke[t];r&&document.removeEventListener(r,e,!1)},raw:xe};function Ee(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($e,{isFullscreen:{get:()=>Boolean(document[xe.fullscreenElement])},element:{enumerable:!0,get:()=>document[xe.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[xe.fullscreenEnabled])}});const Te=new WeakMap;function Ce(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function Le(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:a}=t,i=function(t,e,r){let n=Te.get(t);if(!n){n=new WeakMap,Te.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Ce(n))})}return n}(e,r,n);i.set(o,a),t.element===o&&(i.delete(o),Ce(a))}function Se(t,e,r,n,o=()=>t.element!==t.target){const a=e.child();let i,s,l=!1,c=!1,d=!1,p=!1,u=!1;const h=new Promise((t,e)=>{i=t,s=e});function f(t=!1,e){if(!l){l=!0;try{a.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):i()}}a.add(()=>{l||(l=!0,c=!0,i(),d&&!p&&r&&Le(t))});const m=()=>{d&&!p&&(r?t.element===t.target:o())&&f()};if(Mt(a,t.document,t.changeEvent,m),Mt(a,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(u=!0,d&&!p&&f(!0,new Error("Fullscreen request failed")))}),!a.closed)try{r&&function(t){Te.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&&Le(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:()=>a.dispose()}}function Pe(t,e){const r=u(t).child(),{$player:n,$video:o}=t.template,a=()=>e.element===n||e.element===o;let i,s=a(),l=0,c=s,d=!1,p=!1,f=!1;function m(){if(a())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),m()}),Mt(r,e.document,e.changeEvent,()=>{const r=a();if(r&&function(t){return Te.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void m();if(r===s||h(t))return;s=r;const o=l,i=()=>h(t)||a()!==r||o!==l&&c!==r;t.emit("fullscreen",r),i()||(r&&(t.state="fullscreen"),i()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),Mt(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(f||void 0!==i||a()))&&!h(t)&&t.emit("fullscreenError",r)}),{get:()=>!h(t)&&a(),set(n){if(h(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?p=!1:d&&(p=!0),i?.cancel(),i=void 0,d=!1,!c&&!a())return Promise.resolve();f=!0,d=c;const s=Se(e,r,c,()=>{!h(t)&&c||m()},()=>!a());f=!1,l===o?i=s:s.cancel();const u=s.promise.catch(e=>{throw h(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(i=void 0,d=!1)});return u.catch(()=>{}),u}}}const Me=new WeakSet;function ze(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Ae(t){Me.delete(t),t.removeEventListener("webkitbeginfullscreen",Re),t.removeEventListener("webkitpresentationmodechanged",Re)}function Re(t){if(Me.has(this)&&ze(this,"webkitbeginfullscreen"===t.type)){Ae(this);try{this.webkitExitFullscreen?.()}catch{}}}function Oe(t){Me.add(t),t.addEventListener("webkitbeginfullscreen",Re),t.addEventListener("webkitpresentationmodechanged",Re)}function Ie(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=ze(e),a=o,i=!1,s=0;const l=()=>ze(e,n);function c(r){if(h(t)||(c=e,Me.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(i=!1),d===o)return;o=d;const p=s,u=()=>h(t)||l()!==d||p!==s&&a!==d;t.emit("fullscreen",d),u()||(d&&(t.state="fullscreen"),u()||t.emit("resize"))}r.add(()=>{s++,a=!1,i&&Oe(e),l()&&e.webkitExitFullscreen?.()}),Mt(r,e,"webkitbeginfullscreen",()=>c(!0)),Mt(r,e,"webkitendfullscreen",()=>c(!1)),Mt(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!h(t)&&l(),set(r){if(h(t))return;const n=++s;if(a=Boolean(r),r){if(Ae(e),t.state="fullscreen",h(t)||n!==s)return;i=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(i=!1),o}}else i&&(i=!1,Oe(e)),l()&&e.webkitExitFullscreen()}}}function _e(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,a=()=>{if(h(t))return;const a=function(t){const e=$e.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:()=>Ee(t,e.requestFullscreen,void 0),exit:()=>Ee(r,e.exitFullscreen)}}(o);a?it(t,"fullscreen",Pe(t,a)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",Ie(t)):it(t,"fullscreen",{get:()=>!1,set(){h(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",ct(t,"fullscreen"))};t.once("video:loadedmetadata",a),u(t).add(()=>{t.off("video:loadedmetadata",a)})}function Ne(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function De({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 We(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()&&(De(t.placement),r()))}return u(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(a){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(i){throw new s([a,i])}throw a}}),a=>{if(h(t))return;const i=++n,s=()=>i===n&&!h(t);if(a){r||(r={placement:Ne(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 Fe(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 Ve(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Ye(t,e,r,n){const o=e.child();if(o.closed)return;const a=t.template.$mini;if(a){const t=a.style.display;return o.add(()=>{a.style.display=t}),{element:a,cancelDrag:()=>{},fresh:!1}}const i=t.template.$player.ownerDocument,s=i.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=i.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const a=i.createElement("div");a.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;a.append(l,c),s.append(e,a),Mt(o,e,"click",n),Mt(o,l,"click",()=>{K(t.play())}),Mt(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,a=0,i=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};Mt(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,a=e.clientX,i=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-a}px, ${t.clientY-i}px)`)},c=()=>{if(r.closed||!o||!n())return;const a=e.getBoundingClientRect(),i=Fe(a.left,a.top,Ve(e));s(),e.style.left=`${i.left}px`,e.style.top=`${i.top}px`,t.storage.set("left",i.left),r.closed||t.storage.set("top",i.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,i.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 Be(t){const{$player:e,$video:r}=t.template,n=u(t).child();let o,a,i=0,s=!1,l=!1;const c=()=>!h(t)&&e.classList.contains("art-mini");function d(){if(a){const e=a,r=i;a=void 0;try{De(e)}catch(t){throw r!==i||a||(a=e),t}}}function p(){if(h(t))return;const r=++i;l=!1,d(),h(t)||r!==i||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(h(t))return;const u=++i;if(s)l=!0;else if(t.state="mini",!h(t)&&u===i){a??(a=Ne(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Ye(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void f();if(!o||h(t))return;if(u!==i)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),h(t)||u!==i)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),a=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}:{...Fe(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,Ve(o.element));if(h(t)||u!==i)return;if(o.element.style.left=`${a.left}px`,o.element.style.top=`${a.top}px`,a.reset){if(t.storage.set("top",a.top),h(t)||u!==i)return;t.storage.set("left",a.left)}h(t)||u!==i||t.emit("mini",!0)}catch(m){const r=l;throw l=!1,h(t)||u!==i&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),m}}}return n.add(()=>{i++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?f():p()}}}const He=new WeakSet,je=t=>"picture-in-picture"===t.webkitPresentationMode;function qe(t){He.delete(t),t.removeEventListener("webkitpresentationmodechanged",Ue),t.removeEventListener("enterpictureinpicture",Ue)}function Ue(){if(He.has(this)&&je(this)){qe(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function Xe(t){He.add(t),t.addEventListener("webkitpresentationmodechanged",Ue),t.addEventListener("enterpictureinpicture",Ue)}function Ge(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=u(t).child(),o=()=>r.pictureInPictureElement===e;let a=o(),i=a,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function p(e,r,n){e.then(()=>{!r||!h(t)&&i||d()},e=>{h(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,i=!1,d()}),Mt(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||a)return;const e=c;t.state="pip",!h(t)&&e===c&&o()&&(a=!0,t.emit("pip",!0))}),Mt(n,e,"leavepictureinpicture",()=>{a&&!o()&&(a=!1,t.emit("pip",!1))}),{get:()=>!h(t)&&o()?e:null,set(n){if(h(t))return;const a=++c;if(i=Boolean(n),i?l=!1:s&&(l=!0),s=!1,i){if(t.state="pip",h(t)||c!==a)return;s=!0;try{p(e.requestPictureInPicture(),!0,a)}catch(d){throw c===a&&(s=!1),d}}else o()&&p(r.exitPictureInPicture(),!1,a)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=!1,a=0,i=0;function s(r=!1){if(h(t)||He.has(e))return;const s=je(e);if(s&&(o=!1),s===n&&!r)return;const l=a;s&&(t.state="pip"),h(t)||a!==l||je(e)!==s||(n=s,i++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{a++,o&&Xe(e),je(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Mt(r,e,l,()=>s());return{get:()=>!h(t)&&je(e),set(r){if(h(t))return;const n=++a,l=i;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(qe(e),t.state="pip",h(t)||a!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===a&&(o=!1),c}}else o&&(o=!1,Xe(e)),je(e)&&e.webkitSetPresentationMode("inline");h(t)||n!==a||l!==i||je(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){h(t)||(r.show=e.get("PIP Not Supported"))}})}function Ke(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,a=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:a?.html||"",selector:e,async onSelect(e,r,a){const i=function(t){return t&&Dt.get(t)||(()=>!0)}(a);if(await t.switchQuality(e.url),!h(t)&&i()){const r=`${o.get("Switch Video")}: ${e.html}`;!h(t)&&i()&&(n.show=r)}return e.html}})}})}function Ze(t,e,r,n,o=!0){let a,i=!1;const s=e=>{t.closed||i||(o&&(i=!0,a()),n(e))};return e[o?"once":"on"](r,s),a=t.add(()=>{e.off(r,s)}),s}function Je(t,e,r){return new Promise((n,o)=>{if(h(t)||e===t.url)return void n();const a=fe(t),i=a.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,a.onError=void 0,a.onAssigned=void 0,i.dispose(),t?o(e):n(),t&&a.scope.dispose())};i.add(()=>{l()});const c=()=>!s&&a.active(),d=t=>l(!0,t);a.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=i.child(),u={"video:error":d,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){d(e)}},"video:canplay":()=>{if(!c())return;p.dispose();(async()=>{if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}})().catch(d)}},h=i.child(),f=[],m=Object.keys(u);for(const e of m)Ze(h,t,e,t=>{a.acceptingEvents&&f.push([e,t])},!1);if(ge(t,a,e),!c())return;if(t.notice.show="",!c())return;const g=()=>{if(h.dispose(),!e)return void l();const r={};for(const e of m)r[e]=Ze(p,t,e,u[e]);for(const[t,e]of f){if(!c()||p.closed)break;r[t](e)}f.length=0};a.assigned?g():a.onAssigned=g}catch(p){d(p)}})}function Qe(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,a=!1,i=null;t.on("setBar",async(o,s,l)=>{const c=t.controls?.thumbnails,{url:d,scale:p}=e.thumbnails;if(!c||!d)return;if("hover"===o||"played"===o&&l&&E){if(i||a||(a=!0,i=await j(d,p),a=!1),!i)return;const o=r.clientWidth*s;o>0&&or.clientWidth-u/2?R(a,"left",r.clientWidth-u+"px"):R(a,"left",o-u/2+"px")}(o)}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,a=!1,i=null)}})}function tr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(h(t))return;const o=function(t){const e=de.get(t);return de.delete(t),e||fe(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await At(o.scope)&&o.active()&&(t.loading.show=!0));const a=t.url,i=e.type||Z(n),s=e.customType[i];if(i&&s){if(!(await At(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;Ze(l,t,"video:canplay",()=>{c=!d}),Ze(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,i&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>ve(o,t))}else{if(a&&URL.revokeObjectURL(a),!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(a!==t.url&&(t.option.url=n,o.active()&&t.isReady&&a)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||Ze(o.scope,t,"video:canplay",e)}}catch(a){ve(o,a)}finally{me(o)}}})}class er{constructor(t){tr(t),function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:a}}=t;it(t,"play",{async value(){const i=he(t),s=await a.play();if(!i())return s;const l=e.get("Play");if(!i())return s;if(r.show=l,!i())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${et(t.currentTime)} / ${et(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}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=Q(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)}})}(t),function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=Q(n,0,t.duration))}})}(t),function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>Je(t,e,0);it(t,"switchQuality",{value:e=>Je(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})}(t),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}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(a){if(!h(t)){if(a||(a="default"),"default"===a)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=a.split(":").map(Number),r=ae({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(h(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=a}r.show=`${e.get("Aspect Ratio")}: ${"default"===a?e.get("Default"):a}`,h(t)||t.emit("aspectRatio",a)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=V("canvas");it(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(a){e.show=a,o(a)}})}),it(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(a){e.show=a,o(a)}})}),it(t,"screenshot",{value:async e=>{const n=await t.getDataURL();return J(n,`${e||`artplayer_${et(r.currentTime)}`}.png`),t.emit("screenshot",n),n}})}(t),_e(t),We(t),Ge(t),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})}(t),function(t){it(t,"played",{get:()=>t.currentTime/t.duration})}(t),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)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(h(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!oe(o))return;const a=H(e),i=ae(a,o.width/o.height);i&&!h(t)&&("width"===i.axis?(r.style.width=i.width/a.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=i.height/a.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;it(t,"rect",{get:()=>H(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})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){h(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(tt(o))}`,h(t)||t.emit("flip",o))}})}(t),function(t){it(t,"mini",Be(t))}(t),function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){R(e,"backgroundImage",`url(${t})`)}})}(t),ie(t),function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),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:a}=t.subtitle;if(!n.$track||0===a.length)return;const i=Q(o,-10,10);n.$track.offset=i;for(let e=0;e{switch(t.availability){case"available":a=!0;break;case"not-available":a=!1}}):a=!1,it(t,"airplay",{value(){a?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),Ke(t),Qe(t),be(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const i in e.moreVideoAttr)t.attr(i,e.moreVideoAttr[i]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=Q(e.volume,0,1));const a=r.get("volume");"number"===typeof a&&(n.volume=Q(a,0,1)),e.poster&&R(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const i in e.cssVar)t.cssVar(i,e.cssVar[i]);t.url=e.url}(t)}}const rr=new WeakMap,nr="art-auto-orientation-fullscreen";function or(t){if(rr.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const ar="art-auto-orientation",ir=["width","height","transform-origin","transform"];function sr(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 oe(t)&&oe(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=u(t);let o,a=()=>{};function i(){a(),a=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:a}of e)r.style.setProperty(t,o,a);const n=r.classList.contains(ar);r.classList.remove(ar),n&&(t.isRotate=!1,h(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const a=U();if(h(t)||!t.fullscreenWeb)return;const i=r.ownerDocument.documentElement;o??(o=ir.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=i.clientHeight-a.top-a.bottom+"px",r.style.height=i.clientWidth-a.left-a.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${a.top}px, -${i.clientWidth-a.right}px)`,r.classList.add(ar),t.isRotate=!0,n&&t.emit("resize")}return n.add(i),r=>{h(t)||(r?o?s(!1):e()&&(a(),a=zt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):i())}}(t,n),a=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(nr),t&&(t.cancelled=!0,or(t),t.settled&&rr.get(t.orientation)===t&&rr.delete(t.orientation))}return u(t).add(o),a=>{if(h(t))return;if(!a)return void o();if(n&&!n.cancelled&&rr.get(n.orientation)===n)return;const i=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof i?.lock||"function"!==typeof i.unlock||!e())return;const s={orientation:i,cancelled:!1,settled:!1};n=s,rr.set(i,s);const l=()=>!h(t)&&!s.cancelled&&n===s&&rr.get(i)===s,c=e=>{s.settled=!0;const o=l();rr.get(i)===s&&rr.delete(i),n===s&&(n=void 0),o&&(r.classList.remove(nr),t.notice.show=e)};try{const t=i.lock(i.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,l()?r.classList.add(nr):(or(s),rr.get(i)===s&&rr.delete(i))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",a),u(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",a)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function lr(t){const{i18n:e,icons:r,storage:n,constructor:o,proxy:a,template:{$poster:i}}=t,s=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '}),l=L(".art-auto-playback-last",s),c=L(".art-auto-playback-jump",s),d=L(".art-auto-playback-close",s);A(d,r.close);let p=null;function u(){const r=(n.get("times")||{})[t.option.id||t.option.url];clearTimeout(p),R(s,"display","none"),r&&r>=o.AUTO_PLAYBACK_MIN&&(R(s,"display","flex"),l.textContent=`${e.get("Last Seen")} ${et(r)}`,c.textContent=e.get("Jump Play"),a(d,"click",()=>{R(s,"display","none")}),a(c,"click",()=>{t.seek=r,K(t.play()),R(i,"display","none"),R(s,"display","none")}),t.once("video:timeupdate",()=>{p=setTimeout(()=>{R(s,"display","none")},o.AUTO_PLAYBACK_TIMEOUT)}))}return t.on("video:timeupdate",()=>{if(t.playing){const e=n.get("times")||{},r=Object.keys(e);r.length>o.AUTO_PLAYBACK_MAX&&delete e[r[0]],e[t.option.id||t.option.url]=t.currentTime,n.set("times",e)}}),t.on("ready",u),t.on("restart",u),{name:"auto-playback",get times(){return n.get("times")||{}},clear:()=>n.del("times"),delete(t){const e=n.get("times")||{};return delete e[t],n.set("times",e),e}}}function cr(t){const{constructor:e,proxy:r,template:{$player:n,$video:o}}=t;let a=null,i=!1,s=1;const l=()=>{clearTimeout(a),i&&(i=!1,t.playbackRate=s,M(n,"art-fast-forward"))};return r(o,"touchstart",r=>{1===r.touches.length&&t.playing&&!t.isLock&&(a=setTimeout(()=>{i=!0,s=t.playbackRate,t.playbackRate=e.FAST_FORWARD_VALUE,P(n,"art-fast-forward")},e.FAST_FORWARD_TIME))}),t.on("document:touchmove",l),t.on("document:touchend",l),{name:"fastForward",get state(){return z(n,"art-fast-forward")}}}function dr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return z(n,"art-lock")}function a(){P(n,"art-lock"),t.isLock=!0,t.emit("lock",!0)}function i(){M(n,"art-lock"),t.isLock=!1,t.emit("lock",!1)}return e.add({name:"lock",mounted(e){const n=A(e,r.lock),o=A(e,r.unlock);R(n,"display","none"),t.on("lock",t=>{t?(R(n,"display","inline-flex"),R(o,"display","none")):(R(n,"display","none"),R(o,"display","inline-flex"))})},click(){o()?i():a()}}),{name:"lock",get state(){return o()},set state(t){t?a():i()}}}function pr(t){return t.on("control",e=>{e?M(t.template.$player,"art-mini-progress-bar"):P(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){h(t.art)||!e.miniProgressBar||e.isLive||t.add(pr),!h(t.art)&&e.lock&&E&&t.add(dr),h(t.art)||!e.autoPlayback||e.isLive||t.add(lr),!h(t.art)&&e.autoOrientation&&E&&t.add(sr),!h(t.art)&&e.fastForward&&E&&!e.isLive&&t.add(cr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){G(!h(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(h(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(h(t.art))return t;let o=n;const a=lt(t,o);if(h(t.art))return t;const i=`Cannot add a plugin that already has the same name: ${n}`;return h(t.art)||(G(!a,i),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),h(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const hr=new WeakMap;function fr(t){return!t.closed&&!hr.get(t)}function mr(t){hr.set(t,(hr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(hr.get(t)||1)-1;r?hr.set(t,r):hr.delete(t)}}const gr=new WeakMap,vr=new WeakMap,yr=["$parent","$parents","$option","$events","$formatted"];function br(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=gr.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(gr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function wr(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 xr(t){const e=gr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function kr(t,e){for(let r=0;r{d&&d!==r&&d.dispose()},()=>Pr(t,o)])try{e()}catch(p){p instanceof s?c.push(...p.errors):c.push(p)}if(r.closed||h(t)||(o.push(...a.splice(0)),Sr.set(r,o),Cr.set(e,r),Lr.set(e,n)),i(),c.length)throw new s(c)},dispose(){if(l){l=!1;try{r.dispose()}finally{i()}}}}}function Or(t,e,r,n,o,a){const i=a||zr(e);if(!fr(i)||h(t))return;const s=t.proxy(r,n,e=>{if(fr(i)&&!h(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!fr(i)||h(t)?t.events.remove(s):(xr(e).events.push(s),a&&a!==Cr.get(e)&&a.add(()=>{const r=xr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Ir(t,e,r,n){const o=zr(e);if(!fr(o)||h(t))return;const a=(...e)=>{if(fr(o)&&!h(t))return n(...e)};t.on(r,a),o.add(()=>{t.off(r,a)})}function _r(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:a},template:{$player:i,$setting:s,$bottom:l}}=e;if(!n.setting||!t.show||!r)return;const c=i.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),p=c.width/i.offsetWidth||1,u=(d.left-c.left+d.width/2)/p-i.clientLeft,h=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:a,controlCenter:i,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*a),Math.max(0,r-s-c)),left:Math.max(c,Math.min(i-d/2,e-c-d))}}({containerWidth:i.clientWidth,containerHeight:i.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:a,controlCenter:u,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||E||(u+h.width/2>i.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const Nr=new WeakMap;function Dr(t){Nr.delete(t)}const Wr=new WeakMap;function Fr(t,e){e?Wr.set(t,e):Wr.delete(t)}function Vr(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=Wr.get(t),o=n?.();for(const a of["html","icon","tooltip"]){const t=e.get(a)?.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?.(),Fr(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 Yr=new WeakMap;async function Br(t,e,r,n,o,a,i,s){try{const l=zr(e),c=zr(a),d=(Yr.get(a)||0)+1;Yr.set(a,d);const p=()=>fr(l)&&fr(c)&&!h(t.art)&&Yr.get(a)===d;if(s?.(),!p())return;const u=await o.call(t.art,e,r,n);p()&&Reflect.set(a,i,u)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}}function Hr(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 jr=new WeakMap;function qr(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof s?e.push(...r.errors):e.push(r)}if(e.length)throw new s(e)}function Ur(t){jr.get(t)?.()}function Xr(t,e){const r=t.find(e.name);if(h(t.art))return r||e;if(!r)return t.add(e);Dr(r),Ur(r);const n=Vr(r),o=r.$item,a=o?.parentNode,i=o?.nextSibling,s=o?Hr(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 a=[],i=[];try{for(const e of r){const r=Rr(t.art,e);r&&a.push(r)}for(const t of n)i.push(mr(Er(t)))}catch(l){try{qr([...a.reverse().map(t=>t.resume),...i])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,qr([...a.reverse().map(t=>t.resume),...i]))},dispose(){s&&(s=!1,qr([...a.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Tr(t)),...i]))}}}(t,r);let p=!0,f=!1;const m=()=>{if(!p)return;p=!1;for(const t of d.items)jr.get(t)===m&&jr.delete(t);if(h(t.art))return void d.dispose();const e=r.$item;try{qr([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{a&&o&&a.insertBefore(o,i?.parentNode===a?i:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&_(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(u){console.warn("ArtPlayer setting restore failed:",u)}},g=()=>p&&!h(t.art)&&jr.get(r)===m;for(const u of d.items)jr.set(u,m);const v=u(t.art).add(()=>{p=!1;for(const t of d.items)jr.get(t)===m&&jr.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 a=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,a))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,g),!g())return r;if(t.format(),!g())return r;if(t.createItem(r,!0),!g())return r;if(f=!0,t.render(),!g())return r;p=!1;for(const t of d.items)jr.get(t)===m&&jr.delete(t);return d.dispose(),r}catch(y){throw g()&&m(),y}finally{v()}}const Gr=new WeakMap;function Kr(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",A(r,t)}})}function Zr(t,e,r=!1){const n=function(t){const e=jr.get(t);return()=>!e||jr.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),a=e.$item;let i="selector";lt(e,"switch")&&(i="switch"),lt(e,"range")&&(i="range"),lt(e,"onClick")&&(i="button");const{icons:s,constructor:l}=t.art;if(!n())return;const c=function(t,e,r=u(t)){const n=Cr.get(e);(!n||fr(n)||n.closed)&&Ar(t,e);const o=r.child();return Cr.set(e,o),Lr.set(e,r),Sr.set(o,xr(e).events),o.add(()=>{Pr(t,Sr.get(o))}),o}(t.art,e,Er(o)),d=()=>fr(c)&&!h(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(Fr(e),P(p,"art-setting-item"),R(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=A(p,'
'),u=A(p,'
'),f=document.createElement("div");switch(P(f,"art-setting-item-left-icon"),i){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;A(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;A(f,t)}else A(f,s.check)}if(A(n,f),!d())return;Kr(e,"icon",f);const m=document.createElement("div");P(m,"art-setting-item-left-text");const g=e.html||"";if(!d())return;A(m,g),A(n,m),Kr(e,"html",m);const v=document.createElement("div");P(v,"art-setting-item-right-tooltip");const y=e.tooltip||"";if(!d())return;switch(A(v,y),A(u,v),Kr(e,"tooltip",v),i){case"switch":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=A(t,s.switchOn),n=A(t,s.switchOff),o=e.switch;if(!d())return;R(o?n:r,"display","none"),A(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let a=e.switch;if(!d())return;Fr(e,()=>{const t=a;return()=>{a=t}}),it(e,"switch",{configurable:!0,get:()=>a,set(t){a=t,t?(R(n,"display","none"),R(r,"display",null)):(R(n,"display",null),R(r,"display","none"))}});break}case"range":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",A(t,r);for(const[o,a]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,a,String(t))}P(r,"art-setting-range"),A(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Fr(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");P(t,"art-setting-item-right-icon"),A(t,s.arrowRight),A(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,a=zr(e),i=(t,r,n)=>Or(o,e,t,r,n,a);switch(n){case"switch":e.onSwitch&&i(r,"click",n=>Br(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,a]of[["change","onRange"],["input","onChange"]])e[a]&&i(n,o,o=>Br(t,e,r,o,e[a],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":i(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return Br(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&P(r,"art-current");break;case"button":e.onClick&&i(r,"click",n=>Br(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,p,i),!d())return;it(e,"$item",{configurable:!0,get:()=>p}),r&&a?.parentNode?a.replaceWith(p):A(o,p),e.mounted&&d()&&zt(c,()=>{if(!h(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(f){try{c.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw p.remove(),f}}function Jr(t,e=t.option){if(h(t.art))return;const r=t.cache.get(e);if(r&&!fr(Er(r)))return;const n=(Gr.get(t)||0)+1;Gr.set(t,n);const o=()=>Gr.get(t)===n&&!h(t.art),a=t.active,i=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),s=()=>{t.active=a,a&&t.cache.has(a)&&_(t.cache.get(a),"art-current");for(const[e,r,n]of i)t.$parent.style.setProperty(e,r,n)};if(t.active=e,r)try{_(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!Er(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=u(t.art).child();return $r.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),a=()=>!n.closed&&!h(t.art)&&t.cache.get(e)===r,i=[];try{if(!a())return;P(r,"art-setting-panel"),A(t.$parent,r),_(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=vr.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=u(e).child(),n=(t,n)=>{if(r.closed||h(e))return;const o=(...t)=>{if(!r.closed&&!h(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=W(r,e.controls.setting),o=W(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||h(e)||t.resize()},a=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(a)});const{$player:i,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(i),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(i,{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 a(t){return 1===t?e.get("Normal"):t.toFixed(1)}function i(){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:a(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:a(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{i(),Ir(t,r,"video:ratechange",()=>i())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function a(t){return"default"===t?e.get("Default"):t}function i(){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:a(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:a(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{i(),Ir(t,r,"aspectRatio",()=>i())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function a(t){return e.get(tt(t))}function i(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:a(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:a(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{i(),Ir(t,r,"flip",()=>i())}}}(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)=>{Ir(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){kr(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&&_(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 a=vr.get(t)||{active:!0},i=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nxr(t).parent},$parents:{get:()=>xr(t).parents},$option:{get:()=>xr(t).option},$events:{get:()=>xr(t).events},$formatted:{get:()=>!0}}),gr.set(t,{parent:r,parents:n,option:o,events:i?.events||[],owner:a}),p.generated&&(t.name=e)}for(const p of i)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 kr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){_r(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&&Tr(n)}catch(a){r.push(a)}}try{Ar(t.art,e)}catch(a){a instanceof s?r.push(...a.errors):r.push(a)}}};if(o(e),r.length)throw new s(r)}(this,t)}remove(t){const e=this.find(t);G(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Dr(t),Ur(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const i of[()=>this.inactivate(e),()=>n?.remove(),()=>this.render()])try{i()}catch(a){a instanceof s?o.push(...a.errors):o.push(a)}if(o.length)throw new s(o)}update(t){return Xr(this,t)}add(t,e=this.option){if(h(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={};Nr.set(t,e);const r=()=>Nr.get(t)===e;return{current:r,finish(){r()&&Nr.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(i){if(h(this.art)||o&&!o.current())throw i;if(e[n]===t&&e.splice(n,1),!r&&a){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw i}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,a=document.createElement("div");R(a,"height",`${o}px`),P(a,"art-setting-item"),P(a,"art-setting-item-back");const i=A(a,'
'),s=document.createElement("div");P(s,"art-setting-item-left-icon"),A(s,n),A(i,s),A(i,e.$parent.html),Or(t.art,e.$parent,a,"click",()=>t.render(e.$parents),Er(r)),A(r,a)}(this,t)}createItem(t,e=!1){Zr(this,t,e)}render(t=this.option){Jr(this,t)}}class en{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 rn='.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 nn{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 on=new WeakMap;function an(t){return on.get(t)}function sn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const ln=St;class cn extends ln{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=u(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return on.set(t,n),r.add(()=>{sn(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?O(r,t):R(r,t,e)}update(){!function(t){const e=an(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:a}=t,{$subtitle:i}=a.template;if(i.innerHTML="",!t.activeCues.length)return;if(a.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 ${a.option.subtitle.escape?at(t):t}\n
`).join("")).join("");o()&&(i.innerHTML=s,a.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,a={...o.subtitle,...e,url:t},i=an(this),s=i.revision+1,l=await this.init(a);return!i.scope.closed&&i.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),l}createTrack(t,e){!function(t,e,r){const n=an(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:a}=t,{template:i}=a,s=i.$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=a.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{p.closed||i.$track!==d||a.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{p.closed||i.$track!==d||(a.notice.show=new Error("Failed to load subtitle track"))},p.closed||n.trackRevision!==o)return void p.dispose();s.remove(),i.$video.appendChild(d),i.$track=d;const l=t.textTrack,c=l?a.proxy(l,"cuechange",()=>{p.closed||i.$track!==d||t.update()}):()=>{};if(p.add(()=>{a.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&&sn(n)}}catch(h){if(u)throw h;if(p.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw i.$track=s,l&&l.insertBefore(s,c?.parentNode===l?c:null),h}}(this,t,e)}async init(t){const e=an(this),r=function(t){const e=t.request,r=new nn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:a}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Ct.subtitle),!t.url)return;let i;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||Z(e.url)){case"srt":return{vtt:e.onVttLoad(pt(r))};case"ass":return{vtt:e.onVttLoad(ht(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const l=void 0===s?t.url:i=ut(s.vtt);if(!r.active)return;a.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(s){if(!r.active)return;throw a.innerHTML="",n.show=s,s}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}})}}const dn=`\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
${a}
\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 pn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=L(e.container),G(this.$container,`No container element found by ${e.container}`)),G(B(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();G("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),G(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=d.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,d.set(e,t),o.releaseContainer=()=>{d.get(e)===t&&d.delete(e)}}(t,this.$container,Hr(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return dn}query(t){return L(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=pn.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);!function(t){G(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&&P(this.$player,"art-backdrop"),E&&P(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":P(this.$player,"art-destroy")}}const un=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class hn{on(t,e,r){const n=this.e||(this.e={});let o=un(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 a=!1;function i(...e){a||(a=!0,n.off(t,i),o.apply(r,e))}return i._=e,this.on(t,i,r)}emit(t,...e){const r=this.e||(this.e={}),n=(un(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=un(r,t)?r[t]:void 0,o=[];if(n&&e)for(let a=0,i=n.length;ae.call(this,this)),gn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${gn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=p(t);return e.rollback=void 0,!e.scope.closed})(this)&&mn.push(this)}catch(n){try{f(this,mn,!0,gn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(a){console.warn("Failed to clean up ArtPlayer initialization:",a)}throw n}}static get instances(){return mn}static get version(){return a}static get config(){return i}static get utils(){return mt}static get scheme(){return Ct}static get Emitter(){return hn}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return pn.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:x?"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){f(this,mn,t,gn.REMOVE_SRC_WHEN_DESTROY)}}return gn.STYLE=rn,gn.DEBUG=!1,gn.CONTEXTMENU=!0,gn.NOTICE_TIME=2e3,gn.SETTING_WIDTH=250,gn.SETTING_ITEM_WIDTH=200,gn.SETTING_ITEM_HEIGHT=35,gn.RESIZE_TIME=200,gn.SCROLL_TIME=200,gn.SCROLL_GAP=50,gn.AUTO_PLAYBACK_MAX=10,gn.AUTO_PLAYBACK_MIN=5,gn.AUTO_PLAYBACK_TIMEOUT=3e3,gn.RECONNECT_TIME_MAX=5,gn.RECONNECT_SLEEP_TIME=1e3,gn.CONTROL_HIDE_TIME=3e3,gn.DBCLICK_TIME=300,gn.DBCLICK_FULLSCREEN=!0,gn.MOBILE_DBCLICK_PLAY=!0,gn.MOBILE_CLICK_PLAY=!1,gn.AUTO_ORIENTATION_TIME=200,gn.INFO_LOOP_TIME=1e3,gn.FAST_FORWARD_VALUE=3,gn.FAST_FORWARD_TIME=1e3,gn.TOUCH_MOVE_RATIO=.5,gn.VOLUME_STEP=.1,gn.SEEK_STEP=5,gn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],gn.ASPECT_RATIO=["default","4:3","16:9"],gn.FLIP=["normal","horizontal","vertical"],gn.FULLSCREEN_WEB_IN_BODY=!0,gn.LOG_VERSION=!0,gn.USE_RAF=!1,gn.REMOVE_SRC_WHEN_DESTROY=!0,T&&(window.Artplayer=gn,C("artplayer-style",rn),setTimeout(()=>{gn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${gn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),gn}); +!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{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new l,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 s?t.push(...e.errors):t.push(e)}if(t.length)throw new s(t)}}const c=new WeakMap,d=new WeakMap;function p(t){const e=c.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function u(t){return p(t).scope}function h(t){const e=p(t);return e.destroying||e.scope.closed}function f(t,e,r,n,o=!1){const i=p(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],l=t=>{try{t()}catch(e){a.push(...e instanceof s?e.errors:[e])}};n&&t.template?.$video&&l(()=>t.reset()),l(()=>i.scope.dispose()),l(()=>t.template?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),l(()=>t.emit("destroy")),o&&i.rollback&&l(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const s of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",s);if(a.length)throw a[0]}const m=new WeakMap;function g(t,e){const r=u(t).child();return m.set(e,r),r}function v(t){const e=m.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function y(t){m.get(t)?.dispose()}function b(t,e){return{on:(r,n)=>{!function(t,e,r,n){const o=v(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=v(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)}}const w=globalThis?.CUSTOM_USER_AGENT??("undefined"!==typeof navigator?navigator.userAgent:""),x=/^(?:(?!chrome|android).)*safari/i.test(w),k=/iPad|iPhone|iPod/i.test(w)&&!window.MSStream,$=k||w.includes("Macintosh")&&navigator.maxTouchPoints>=1,E=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(w)||$,T="undefined"!==typeof window&&"undefined"!==typeof document;function C(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function L(t,e=document){return e.querySelector(t)}function S(t,e=document){return Array.from(e.querySelectorAll(t))}function P(t,e){return t.classList.add(e)}function M(t,e){return t.classList.remove(e)}function z(t,e){return t.classList.contains(e)}function A(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function R(t,e,r){return t.style[e]=r,t}function O(t,e){for(const r in e)R(t,r,e[r]);return t}function I(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function _(t,e){I(t).forEach(t=>M(t,e)),P(t,e)}function N(t,e,r="top"){E||(t.setAttribute("aria-label",e),P(t,"hint--rounded"),P(t,`hint--${r}`))}function D(t,e){return j(t).includes(e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function W(t){return document.createElement(t)}function V(t="",e=""){const r=W("i");return P(r,"art-icon"),P(r,`art-icon-${t}`),A(r,e),r}function Y(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function B(t){return t.getBoundingClientRect()}function H(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function j(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function q(){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;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}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:P,append:A,assToVtt:ut,capitalize:Q,clamp:J,createElement:W,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:j,getExt:K,getIcon:V,getRect:B,getSafeAreaInsets:q,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:z,includeFromEvent:D,inverseClass:_,isBrowser:T,isIOS:k,isIOS13:$,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:E,isSafari:x,loadImg:H,mergeDeep:ct,query:L,queryAll:S,remove:function(t){return t.parentNode.removeChild(t)},removeClass:M,replaceElement:F,secondToTime:tt,setStyle:R,setStyleText:C,setStyles:O,siblings:I,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:Y,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:N,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:w,vttToBlob:pt},Symbol.toStringTag,{value:"Module"}));function ft(t,e){return A(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 z(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?P(e,r):M(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t;if(h(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=g(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){P(t,`art-${r}`),P(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):A(e,t),i.html&&A(t,i.html),i.style&&O(t,i.style),i.tooltip&&N(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{y(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{y(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,g(t,this.$parent),E||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=b(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}=b(e,t),n=L('[data-value="1"]',t);n&&_(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&_(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}=b(e,t),n=L('[data-value="default"]',t);n&&_(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(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}=b(e,t),n=L('[data-value="normal"]',t);n&&_(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(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}=B(e),{height:c,width:d}=B(r);let p=n-s,u=o-l;n+d>s+a&&(p=a-d),o+c>l+i&&(u=i-c),O(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{D(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)})})}function zt(t,e){const{$progress:r}=t.template,{left:n}=B(r),o=J((E?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 At(t,e,r=()=>!0){if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=zt(t,e);t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Rt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=v(e),{on:a}=b(t,e);let s=()=>{};const l=mt(".art-progress-hover",e),c=mt(".art-progress-loaded",e),d=mt(".art-progress-played",e),p=mt(".art-progress-highlight",e),u=mt(".art-progress-indicator",e),h=mt(".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?R(h,"left",0):o>e.clientWidth-a/2?R(h,"left",e.clientWidth-a+"px"):R(h,"left",o-a/2+"px")}r.indicator?A(u,r.indicator):R(u,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&E;if("loaded"===r&&R(c,"width",100*n+"%"),"hover"===r&&(R(l,"width",100*n+"%"),D(a,p)?function(r){const{width:n}=zt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const i=h.clientWidth;n<=i/2?R(h,"left",0):n>e.clientWidth-i/2?R(h,"left",e.clientWidth-i+"px"):R(h,"left",n-i/2+"px")}(a):f(a),0===n?M(o,"art-progress-hover"):P(o,"art-progress-hover")),"played"===r&&(R(d,"width",100*n+"%"),R(u,"left",100*n+"%")),m){P(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=Pt(i,()=>{M(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 Ot(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Rt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=b(t,e);if(!E){let e=!1;i(r,"click",e=>{e.target!==n&&At(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=zt(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=zt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function It(t){const{option:e}=t.art;e.isLive||t.add(Ot({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}=b(e,t),{icons:o,i18n:i}=e,a=ft(t,o.play),s=ft(t,o.pause);function l(){R(a,"display","flex"),R(s,"display","none")}function c(){R(a,"display","none"),R(s,"display","flex")}N(a,i.get("Play")),N(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}=b(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,'
'),p=ft(d,'
'),u=ft(p,'
'),h=ft(d,'
');function f(t){const{top:e,height:r}=B(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)R(i,"display","none"),R(a,"display","flex"),R(h,"top","100%"),R(u,"top","100%"),c.textContent="0";else{const t=100*e.volume;R(i,"display","flex"),R(a,"display","none"),R(h,"top",100-t+"%"),R(u,"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}),E)R(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=>({...t,style:E?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=b(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&&!u(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!E&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=b(e,t),{icons:n}=e;ft(t,n.screenshot),r(t,"click",()=>{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}=b(e,t),{icons:o,i18n:i}=e;ft(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{N(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}=b(e,t),{icons:o,i18n:i}=e;ft(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{N(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}=b(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}=b(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenWebOn),s=ft(t,o.fullscreenWebOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(N(t,i.get("Exit Web Fullscreen")),R(a,"display","none"),R(s,"display","inline-flex")):(N(t,i.get("Web Fullscreen")),R(a,"display","inline-flex"),R(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}=b(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenOn),s=ft(t,o.fullscreenOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(N(t,i.get("Exit Fullscreen")),R(a,"display","none"),R(s,"display","inline-flex")):(N(t,i.get("Fullscreen")),R(a,"display","inline-flex"),R(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rNt.get(t).option.selector}),it(t,"$control_item",{get:()=>Nt.get(t).item}),it(t,"$control_value",{get:()=>Nt.get(t).value})),Nt.set(t,e)}function Ft(t,e){t.innerHTML=e}function Wt(t,e,r,n,o){const{proxy:i}=t.events,a=v(n),s=r.selector;P(n,"art-control-selector");const l=document.createElement("div");P(l,"art-selector-value"),A(l,r.html),n.textContent="",A(n,l);const c=ft(n,'
');for(let u=0;u{if(a.closed)return;const o=j(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 _t.set(t,e),()=>{_t.get(t)===e&&_t.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()&&Ft(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Vt 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;g(t,n);const{on:o}=b(t,n);o("mousemove",()=>{E||(this.show=!0)}),o("click",()=>{E?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=D(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?(M(r,"art-hide-cursor"),P(r,"art-hover"),this.timer=Date.now()):(P(r,"art-hide-cursor"),M(r,"art-hover"))}),this.init(),u(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=v(e),{on:i}=b(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(){It(this)}add(t){if(h(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){Ft(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Yt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(h(t))return;const n=D(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),u(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(h(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),h(t))return;(!E||!t.isLock&&i)&&G(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),h(t))return;E?!t.isLock&&s&&G(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}const Bt=new WeakMap,Ht=new WeakMap,jt=new WeakMap;function qt(t){return jt.get(t)||u(t)}function Ut(t){const e=Bt.get(t),r=jt.get(t);return()=>Bt.get(t)===e&&(!e||e.active())&&jt.get(t)===r&&(!r||!r.closed)}function Xt(t){const e=jt.get(t),r=u(t).child(),n=r.child();jt.set(t,r),r.add(()=>{jt.get(t)===r&&jt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!h(t)&&!n.closed&&Bt.get(t)===o};return Bt.set(t,o),n.add(()=>{Bt.get(t)===o&&Bt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function Gt(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function Kt(t,e,r){Ht.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Ht.get(t)===e&&(Ht.delete(t),Gt(e))}}function Zt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Jt(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!h(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),u(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(h(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:Ut(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{At(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(h(t))return;const n=(...e)=>{if(!h(t))return r(...e)};t.on(e,n),u(t).add(()=>{t.off(e,n)})}}function ie(t){if(!t.constructor.USE_RAF)return;const e=u(t);let r=()=>{};const n=()=>{h(t)||(t.playing&&t.emit("raf"),h(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:u(e),cleaning:!1})}(this,t),u(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Yt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{h(t)||(P(r,"art-hover"),t.emit("hover",!0,e))},e=>{h(t)||(M(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{h(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(),h(t)||(t.aspectRatio=e,h(t)||(n.show=""))});const i=u(t);let a=()=>{};const s=()=>{h(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(!E||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=u(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)),h(t)||(s=!0,Pt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;u(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(h(t))return;const a=++n,s={disposers:[]},l=()=>a!==n||h(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||h(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}),E||this.init()}init(){const t=this.art;if(h(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(!h(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:()=>V(r,e[r])})}}class me extends Ct{constructor(t){super(t),this.name="info",E||this.init()}init(){const{proxy:t,constructor:e,template:{$infoPanel:r,$infoClose:n,$video:o}}=this.art;t(n,"click",()=>{this.show=!1});let i=()=>{};const a=S("[data-video]",r)||[];this.art.on("destroy",()=>i());const s=u(this.art);!function t(){for(let e=0;e{R(o,"display","none"),R(i,"display",null)}),n.proxy(e.$state,"click",()=>G(t.play()))}}class be{constructor(t){this.art=t,this.timer=null,u(t).add(()=>this.destroy()),t.on("destroy",()=>this.destroy())}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}set show(t){if(u(this.art).closed)return;const{constructor:e,template:{$player:r,$noticeInner:n}}=this.art;t?(n.textContent=t instanceof Error?t.message.trim():t,P(r,"art-notice-show"),clearTimeout(this.timer),this.timer=setTimeout(()=>{n.textContent="",M(r,"art-notice-show")},e.NOTICE_TIME)):M(r,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function we({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function xe(t,e){if(!we(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 we(r)?r:void 0}function ke(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(h(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!we(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||h(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function $e(t,e,r,n=!1){const o=e=>{h(t)||r(e)};t[n?"once":"on"](e,o),u(t).add(()=>{t.off(e,o)})}function Ee(t,e,r){for(const[n,o]of e){if(h(t)||r&&!r())return;t[n].show=o}}function Te(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=qt(t),l=0;return{reset(){l=0,a?.dispose(),M(i,"art-error")},loadStart(){M(i,"art-error")},schedule(c){(async c=>{if(h(t))return;const d=qt(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=()=>!h(t)&&!p.closed&&d===qt(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Ce(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{h(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Te(t);!function(t,e){$e(t,"video:canplay",()=>{e.reset(),Ee(t,[["loading",!1]])}),$e(t,"video:canplay",()=>{Ee(t,[["loading",!1],["controls",!0],["mask",!0]]),h(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;$e(t,"video:ended",()=>{if(e.loop){const e=Ut(t);if(t.seek=0,h(t)||!e())return;G(t.play()),e()&&Ee(t,[["controls",!1],["mask",!1]],e)}else Ee(t,[["controls",!0],["mask",!0]])})}(t),$e(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;$e(t,"video:loadedmetadata",()=>{t.emit("resize"),E&&Ee(t,[["loading",!1],["controls",!0],["mask",!0]])}),$e(t,"video:loadstart",()=>{e.loadStart(),Ee(t,[["loading",!0],["mask",!1],["controls",!0]])}),$e(t,"video:pause",()=>{Ee(t,[["controls",!0],["mask",!0]])}),$e(t,"video:play",()=>{Ee(t,[["mask",!1]]),h(t)||R(r,"display","none")}),$e(t,"video:playing",()=>Ee(t,[["mask",!1]])),$e(t,"video:progress",()=>{t.playing&&Ee(t,[["loading",!1]])}),$e(t,"video:seeked",()=>Ee(t,[["loading",!1],["mask",!0]])),$e(t,"video:seeking",()=>Ee(t,[["loading",!0],["mask",!1]])),$e(t,"video:timeupdate",()=>Ee(t,[["mask",!1]])),$e(t,"video:waiting",()=>Ee(t,[["loading",!0],["mask",!1]]))}(t,e)}const Le=[["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"]],Se=(()=>{if("undefined"===typeof document)return!1;const t=Le[0],e={};for(const r of Le){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Pe={change:Se.fullscreenchange,error:Se.fullscreenerror},Me={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Me.off("change",o),r()};Me.on("change",o);const i=t[Se.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Me.isFullscreen)return void t();const r=()=>{Me.off("change",r),t()};Me.on("change",r);const n=document[Se.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Me.isFullscreen?Me.exit():Me.request(t,e),onchange(t){Me.on("change",t)},onerror(t){Me.on("error",t)},on(t,e){const r=Pe[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Pe[t];r&&document.removeEventListener(r,e,!1)},raw:Se};function ze(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(Me,{isFullscreen:{get:()=>Boolean(document[Se.fullscreenElement])},element:{enumerable:!0,get:()=>document[Se.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Se.fullscreenEnabled])}});const Ae=new WeakMap;function Re(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function Oe(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ae.get(t);if(!n){n=new WeakMap,Ae.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Re(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Re(i))}function Ie(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&&Oe(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){Ae.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&&Oe(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 _e(t,e){const r=u(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,f=!1;function m(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),m()}),St(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return Ae.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void m();if(r===s||h(t))return;s=r;const o=l,a=()=>h(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&&(f||void 0!==a||i()))&&!h(t)&&t.emit("fullscreenError",r)}),{get:()=>!h(t)&&i(),set(n){if(h(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();f=!0,d=c;const s=Ie(e,r,c,()=>{!h(t)&&c||m()},()=>!i());f=!1,l===o?a=s:s.cancel();const u=s.promise.catch(e=>{throw h(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return u.catch(()=>{}),u}}}const Ne=new WeakSet;function De(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Fe(t){Ne.delete(t),t.removeEventListener("webkitbeginfullscreen",We),t.removeEventListener("webkitpresentationmodechanged",We)}function We(t){if(Ne.has(this)&&De(this,"webkitbeginfullscreen"===t.type)){Fe(this);try{this.webkitExitFullscreen?.()}catch{}}}function Ve(t){Ne.add(t),t.addEventListener("webkitbeginfullscreen",We),t.addEventListener("webkitpresentationmodechanged",We)}function Ye(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=De(e),i=o,a=!1,s=0;const l=()=>De(e,n);function c(r){if(h(t)||(c=e,Ne.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=()=>h(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&&Ve(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:()=>!h(t)&&l(),set(r){if(h(t))return;const n=++s;if(i=Boolean(r),r){if(Fe(e),t.state="fullscreen",h(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,Ve(e)),l()&&e.webkitExitFullscreen()}}}function Be(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(h(t))return;const i=function(t){const e=Me.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:()=>ze(t,e.requestFullscreen,void 0),exit:()=>ze(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",_e(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",Ye(t)):it(t,"fullscreen",{get:()=>!1,set(){h(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",lt(t,"fullscreen"))};t.once("video:loadedmetadata",i),u(t).add(()=>{t.off("video:loadedmetadata",i)})}function He(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function je({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 qe(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()&&(je(t.placement),r()))}return u(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 s([i,a])}throw i}}),i=>{if(h(t))return;const a=++n,s=()=>a===n&&!h(t);if(i){r||(r={placement:He(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 Ue(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 Xe(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Ge(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=Ue(i.left,i.top,Xe(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 Ke(t){const{$player:e,$video:r}=t.template,n=u(t).child();let o,i,a=0,s=!1,l=!1;const c=()=>!h(t)&&e.classList.contains("art-mini");function d(){if(i){const e=i,r=a;i=void 0;try{je(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(h(t))return;const r=++a;l=!1,d(),h(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(h(t))return;const u=++a;if(s)l=!0;else if(t.state="mini",!h(t)&&u===a){i??(i=He(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Ge(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void f();if(!o||h(t))return;if(u!==a)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),h(t)||u!==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}:{...Ue(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,Xe(o.element));if(h(t)||u!==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),h(t)||u!==a)return;t.storage.set("left",i.left)}h(t)||u!==a||t.emit("mini",!0)}catch(m){const r=l;throw l=!1,h(t)||u!==a&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),m}}}return n.add(()=>{a++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?f():p()}}}const Ze=new WeakSet,Je=t=>"picture-in-picture"===t.webkitPresentationMode;function Qe(t){Ze.delete(t),t.removeEventListener("webkitpresentationmodechanged",tr),t.removeEventListener("enterpictureinpicture",tr)}function tr(){if(Ze.has(this)&&Je(this)){Qe(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function er(t){Ze.add(t),t.addEventListener("webkitpresentationmodechanged",tr),t.addEventListener("enterpictureinpicture",tr)}function rr(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=u(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||!h(t)&&a||d()},e=>{h(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",!h(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),St(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!h(t)&&o()?e:null,set(n){if(h(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",h(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=u(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(h(t)||Ze.has(e))return;const s=Je(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),h(t)||i!==l||Je(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&er(e),Je(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])St(r,e,l,()=>s());return{get:()=>!h(t)&&Je(e),set(r){if(h(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(Qe(e),t.state="pip",h(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===i&&(o=!1),c}}else o&&(o=!1,er(e)),Je(e)&&e.webkitSetPresentationMode("inline");h(t)||n!==i||l!==a||Je(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){h(t)||(r.show=e.get("PIP Not Supported"))}})}function nr(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&&_t.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!h(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!h(t)&&a()&&(n.show=r)}return e.html}})}})}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(h(t)||e===t.url)return void n();const i=Xt(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(),u={"video:error":d,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){d(e)}},"video:canplay":()=>{if(!c())return;p.dispose();(async()=>{if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}})().catch(d)}},h=a.child(),f=[],m=Object.keys(u);for(const e of m)or(h,t,e,t=>{i.acceptingEvents&&f.push([e,t])},!1);if(Kt(t,i,e),!c())return;if(t.notice.show="",!c())return;const g=()=>{if(h.dispose(),!e)return void l();const r={};for(const e of m)r[e]=or(p,t,e,u[e]);for(const[t,e]of f){if(!c()||p.closed)break;r[t](e)}f.length=0};i.assigned?g():i.onAssigned=g}catch(p){d(p)}})}function ar(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",async(o,s,l)=>{const c=t.controls?.thumbnails,{url:d,scale:p}=e.thumbnails;if(!c||!d)return;if("hover"===o||"played"===o&&l&&E){if(a||i||(i=!0,a=await H(d,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-u/2?R(i,"left",r.clientWidth-u+"px"):R(i,"left",o-u/2+"px")}(o)}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function sr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(h(t))return;const o=function(t){const e=Ht.get(t);return Ht.delete(t),e||Xt(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=>Zt(o,t))}else{if(i&&URL.revokeObjectURL(i),!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){Zt(o,i)}finally{Gt(o)}}})}class lr{constructor(t){sr(t),function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=Ut(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()})}(t),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}})}(t),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)}})}(t),function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=J(n,0,t.duration))}})}(t),function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),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})}(t),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}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!h(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=xe({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(h(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}`,h(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=W("canvas");it(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),it(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),it(t,"screenshot",{value:async e=>{const n=await t.getDataURL();return Z(n,`${e||`artplayer_${tt(r.currentTime)}`}.png`),t.emit("screenshot",n),n}})}(t),Be(t),qe(t),rr(t),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})}(t),function(t){it(t,"played",{get:()=>t.currentTime/t.duration})}(t),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)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(h(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!we(o))return;const i=B(e),a=xe(i,o.width/o.height);a&&!h(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}))}})}(t),function(t){const e=t;it(t,"rect",{get:()=>B(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})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){h(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,h(t)||t.emit("flip",o))}})}(t),function(t){it(t,"mini",Ke(t))}(t),function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){R(e,"backgroundImage",`url(${t})`)}})}(t),ke(t),function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),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{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,it(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),nr(t),ar(t),Ce(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=J(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=J(i,0,1)),e.poster&&R(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const cr=new WeakMap,dr="art-auto-orientation-fullscreen";function pr(t){if(cr.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const ur="art-auto-orientation",hr=["width","height","transform-origin","transform"];function fr(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 we(t)&&we(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=u(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,h(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=q();if(h(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=hr.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=>{h(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(dr),t&&(t.cancelled=!0,pr(t),t.settled&&cr.get(t.orientation)===t&&cr.delete(t.orientation))}return u(t).add(o),i=>{if(h(t))return;if(!i)return void o();if(n&&!n.cancelled&&cr.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,cr.set(a,s);const l=()=>!h(t)&&!s.cancelled&&n===s&&cr.get(a)===s,c=e=>{s.settled=!0;const o=l();cr.get(a)===s&&cr.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,l()?r.classList.add(dr):(pr(s),cr.get(a)===s&&cr.delete(a))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),u(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function mr(t){const{i18n:e,icons:r,storage:n,constructor:o,proxy:i,template:{$poster:a}}=t,s=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '}),l=L(".art-auto-playback-last",s),c=L(".art-auto-playback-jump",s),d=L(".art-auto-playback-close",s);A(d,r.close);let p=null;function u(){const r=(n.get("times")||{})[t.option.id||t.option.url];clearTimeout(p),R(s,"display","none"),r&&r>=o.AUTO_PLAYBACK_MIN&&(R(s,"display","flex"),l.textContent=`${e.get("Last Seen")} ${tt(r)}`,c.textContent=e.get("Jump Play"),i(d,"click",()=>{R(s,"display","none")}),i(c,"click",()=>{t.seek=r,G(t.play()),R(a,"display","none"),R(s,"display","none")}),t.once("video:timeupdate",()=>{p=setTimeout(()=>{R(s,"display","none")},o.AUTO_PLAYBACK_TIMEOUT)}))}return t.on("video:timeupdate",()=>{if(t.playing){const e=n.get("times")||{},r=Object.keys(e);r.length>o.AUTO_PLAYBACK_MAX&&delete e[r[0]],e[t.option.id||t.option.url]=t.currentTime,n.set("times",e)}}),t.on("ready",u),t.on("restart",u),{name:"auto-playback",get times(){return n.get("times")||{}},clear:()=>n.del("times"),delete(t){const e=n.get("times")||{};return delete e[t],n.set("times",e),e}}}function gr(t){const{constructor:e,proxy:r,template:{$player:n,$video:o}}=t;let i=null,a=!1,s=1;const l=()=>{clearTimeout(i),a&&(a=!1,t.playbackRate=s,M(n,"art-fast-forward"))};return r(o,"touchstart",r=>{1===r.touches.length&&t.playing&&!t.isLock&&(i=setTimeout(()=>{a=!0,s=t.playbackRate,t.playbackRate=e.FAST_FORWARD_VALUE,P(n,"art-fast-forward")},e.FAST_FORWARD_TIME))}),t.on("document:touchmove",l),t.on("document:touchend",l),{name:"fastForward",get state(){return z(n,"art-fast-forward")}}}function vr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return z(n,"art-lock")}function i(){P(n,"art-lock"),t.isLock=!0,t.emit("lock",!0)}function a(){M(n,"art-lock"),t.isLock=!1,t.emit("lock",!1)}return e.add({name:"lock",mounted(e){const n=A(e,r.lock),o=A(e,r.unlock);R(n,"display","none"),t.on("lock",t=>{t?(R(n,"display","inline-flex"),R(o,"display","none")):(R(n,"display","none"),R(o,"display","inline-flex"))})},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function yr(t){return t.on("control",e=>{e?M(t.template.$player,"art-mini-progress-bar"):P(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class br{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){h(t.art)||!e.miniProgressBar||e.isLive||t.add(yr),!h(t.art)&&e.lock&&E&&t.add(vr),h(t.art)||!e.autoPlayback||e.isLive||t.add(mr),!h(t.art)&&e.autoOrientation&&E&&t.add(fr),!h(t.art)&&e.fastForward&&E&&!e.isLive&&t.add(gr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!h(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(h(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(h(t.art))return t;let o=n;const i=st(t,o);if(h(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return h(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),h(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const wr=new WeakMap;function xr(t){return!t.closed&&!wr.get(t)}function kr(t){wr.set(t,(wr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(wr.get(t)||1)-1;r?wr.set(t,r):wr.delete(t)}}const $r=new WeakMap,Er=new WeakMap,Tr=["$parent","$parents","$option","$events","$formatted"];function Cr(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=$r.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($r.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function Lr(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 Sr(t){const e=$r.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Pr(t,e){for(let r=0;r{d&&d!==r&&d.dispose()},()=>_r(t,o)])try{e()}catch(p){p instanceof s?c.push(...p.errors):c.push(p)}if(r.closed||h(t)||(o.push(...i.splice(0)),Ir.set(r,o),Rr.set(e,r),Or.set(e,n)),a(),c.length)throw new s(c)},dispose(){if(l){l=!1;try{r.dispose()}finally{a()}}}}}function Vr(t,e,r,n,o,i){const a=i||Dr(e);if(!xr(a)||h(t))return;const s=t.proxy(r,n,e=>{if(xr(a)&&!h(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!xr(a)||h(t)?t.events.remove(s):(Sr(e).events.push(s),i&&i!==Rr.get(e)&&i.add(()=>{const r=Sr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Yr(t,e,r,n){const o=Dr(e);if(!xr(o)||h(t))return;const i=(...e)=>{if(xr(o)&&!h(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Br(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(),p=c.width/a.offsetWidth||1,u=(d.left-c.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: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:u,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||E||(u+h.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const Hr=new WeakMap;function jr(t){Hr.delete(t)}const qr=new WeakMap;function Ur(t,e){e?qr.set(t,e):qr.delete(t)}function Xr(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=qr.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?.(),Ur(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 Gr=new WeakMap;async function Kr(t,e,r,n,o,i,a,s){try{const l=Dr(e),c=Dr(i),d=(Gr.get(i)||0)+1;Gr.set(i,d);const p=()=>xr(l)&&xr(c)&&!h(t.art)&&Gr.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 Zr(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 Jr=new WeakMap;function Qr(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof s?e.push(...r.errors):e.push(r)}if(e.length)throw new s(e)}function tn(t){Jr.get(t)?.()}function en(t,e){const r=t.find(e.name);if(h(t.art))return r||e;if(!r)return t.add(e);jr(r),tn(r);const n=Xr(r),o=r.$item,i=o?.parentNode,a=o?.nextSibling,s=o?Zr(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=Wr(t.art,e);r&&i.push(r)}for(const t of n)a.push(kr(zr(t)))}catch(l){try{Qr([...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,Qr([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,Qr([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Ar(t)),...a]))}}}(t,r);let p=!0,f=!1;const m=()=>{if(!p)return;p=!1;for(const t of d.items)Jr.get(t)===m&&Jr.delete(t);if(h(t.art))return void d.dispose();const e=r.$item;try{Qr([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{i&&o&&i.insertBefore(o,a?.parentNode===i?a:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&_(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(u){console.warn("ArtPlayer setting restore failed:",u)}},g=()=>p&&!h(t.art)&&Jr.get(r)===m;for(const u of d.items)Jr.set(u,m);const v=u(t.art).add(()=>{p=!1;for(const t of d.items)Jr.get(t)===m&&Jr.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,g),!g())return r;if(t.format(),!g())return r;if(t.createItem(r,!0),!g())return r;if(f=!0,t.render(),!g())return r;p=!1;for(const t of d.items)Jr.get(t)===m&&Jr.delete(t);return d.dispose(),r}catch(y){throw g()&&m(),y}finally{v()}}const rn=new WeakMap;function nn(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",A(r,t)}})}function on(t,e,r=!1){const n=function(t){const e=Jr.get(t);return()=>!e||Jr.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=u(t)){const n=Rr.get(e);(!n||xr(n)||n.closed)&&Fr(t,e);const o=r.child();return Rr.set(e,o),Or.set(e,r),Ir.set(o,Sr(e).events),o.add(()=>{_r(t,Ir.get(o))}),o}(t.art,e,zr(o)),d=()=>xr(c)&&!h(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(Ur(e),P(p,"art-setting-item"),R(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=A(p,'
'),u=A(p,'
'),f=document.createElement("div");switch(P(f,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;A(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;A(f,t)}else A(f,s.check)}if(A(n,f),!d())return;nn(e,"icon",f);const m=document.createElement("div");P(m,"art-setting-item-left-text");const g=e.html||"";if(!d())return;A(m,g),A(n,m),nn(e,"html",m);const v=document.createElement("div");P(v,"art-setting-item-right-tooltip");const y=e.tooltip||"";if(!d())return;switch(A(v,y),A(u,v),nn(e,"tooltip",v),a){case"switch":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=A(t,s.switchOn),n=A(t,s.switchOff),o=e.switch;if(!d())return;R(o?n:r,"display","none"),A(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;Ur(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(R(n,"display","none"),R(r,"display",null)):(R(n,"display",null),R(r,"display","none"))}});break}case"range":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",A(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))}P(r,"art-setting-range"),A(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Ur(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");P(t,"art-setting-item-right-icon"),A(t,s.arrowRight),A(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=Dr(e),a=(t,r,n)=>Vr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>Kr(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=>Kr(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 Kr(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&P(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>Kr(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):A(o,p),e.mounted&&d()&&Pt(c,()=>{if(!h(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(f){try{c.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw p.remove(),f}}function an(t,e=t.option){if(h(t.art))return;const r=t.cache.get(e);if(r&&!xr(zr(r)))return;const n=(rn.get(t)||0)+1;rn.set(t,n);const o=()=>rn.get(t)===n&&!h(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)&&_(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{_(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!zr(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=u(t.art).child();return Mr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),i=()=>!n.closed&&!h(t.art)&&t.cache.get(e)===r,a=[];try{if(!i())return;P(r,"art-setting-panel"),A(t.$parent,r),_(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Er.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=u(e).child(),n=(t,n)=>{if(r.closed||h(e))return;const o=(...t)=>{if(!r.closed&&!h(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=D(r,e.controls.setting),o=D(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||h(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(),Yr(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(),Yr(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(),Yr(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)=>{Yr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Pr(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&&_(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=Er.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nSr(t).parent},$parents:{get:()=>Sr(t).parents},$option:{get:()=>Sr(t).option},$events:{get:()=>Sr(t).events},$formatted:{get:()=>!0}}),$r.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 Pr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){Br(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&&Ar(n)}catch(i){r.push(i)}}try{Fr(t.art,e)}catch(i){i instanceof s?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new s(r)}(this,t)}remove(t){const e=this.find(t);X(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{jr(t),tn(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 s?o.push(...i.errors):o.push(i)}if(o.length)throw new s(o)}update(t){return en(this,t)}add(t,e=this.option){if(h(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={};Hr.set(t,e);const r=()=>Hr.get(t)===e;return{current:r,finish(){r()&&Hr.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(h(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");R(i,"height",`${o}px`),P(i,"art-setting-item"),P(i,"art-setting-item-back");const a=A(i,'
'),s=document.createElement("div");P(s,"art-setting-item-left-icon"),A(s,n),A(a,s),A(a,e.$parent.html),Vr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),zr(r)),A(r,i)}(this,t)}createItem(t,e=!1){on(this,t,e)}render(t=this.option){an(this,t)}}class cn{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 dn='.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 pn{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 un=new WeakMap;function hn(t){return un.get(t)}function fn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const mn=Ct;class gn extends mn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=u(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return un.set(t,n),r.add(()=>{fn(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?O(r,t):R(r,t,e)}update(){!function(t){const e=hn(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=hn(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=hn(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&&fn(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=hn(this),r=function(t){const e=t.request,r=new pn(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 vn=`\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 yn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=L(e.container),X(this.$container,`No container element found by ${e.container}`)),X(Y(),"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=d.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,d.set(e,t),o.releaseContainer=()=>{d.get(e)===t&&d.delete(e)}}(t,this.$container,Zr(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return vn}query(t){return L(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=yn.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);!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&&P(this.$player,"art-backdrop"),E&&P(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":P(this.$player,"art-destroy")}}const bn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class wn{on(t,e,r){const n=this.e||(this.e={});let o=bn(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=(bn(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=bn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;ie.call(this,this)),$n.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${$n.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=p(t);return e.rollback=void 0,!e.scope.closed})(this)&&kn.push(this)}catch(n){try{f(this,kn,!0,$n.REMOVE_SRC_WHEN_DESTROY,!0)}catch(i){console.warn("Failed to clean up ArtPlayer initialization:",i)}throw n}}static get instances(){return kn}static get version(){return i}static get config(){return a}static get utils(){return ht}static get scheme(){return Et}static get Emitter(){return wn}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return yn.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:x?"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){f(this,kn,t,$n.REMOVE_SRC_WHEN_DESTROY)}}return $n.STYLE=dn,$n.DEBUG=!1,$n.CONTEXTMENU=!0,$n.NOTICE_TIME=2e3,$n.SETTING_WIDTH=250,$n.SETTING_ITEM_WIDTH=200,$n.SETTING_ITEM_HEIGHT=35,$n.RESIZE_TIME=200,$n.SCROLL_TIME=200,$n.SCROLL_GAP=50,$n.AUTO_PLAYBACK_MAX=10,$n.AUTO_PLAYBACK_MIN=5,$n.AUTO_PLAYBACK_TIMEOUT=3e3,$n.RECONNECT_TIME_MAX=5,$n.RECONNECT_SLEEP_TIME=1e3,$n.CONTROL_HIDE_TIME=3e3,$n.DBCLICK_TIME=300,$n.DBCLICK_FULLSCREEN=!0,$n.MOBILE_DBCLICK_PLAY=!0,$n.MOBILE_CLICK_PLAY=!1,$n.AUTO_ORIENTATION_TIME=200,$n.INFO_LOOP_TIME=1e3,$n.FAST_FORWARD_VALUE=3,$n.FAST_FORWARD_TIME=1e3,$n.TOUCH_MOVE_RATIO=.5,$n.VOLUME_STEP=.1,$n.SEEK_STEP=5,$n.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],$n.ASPECT_RATIO=["default","4:3","16:9"],$n.FLIP=["normal","horizontal","vertical"],$n.FULLSCREEN_WEB_IN_BODY=!0,$n.LOG_VERSION=!0,$n.USE_RAF=!1,$n.REMOVE_SRC_WHEN_DESTROY=!0,T&&(window.Artplayer=$n,C("artplayer-style",dn),setTimeout(()=>{$n.LOG_VERSION&&console.log(`%c ArtPlayer %c ${$n.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),$n}); diff --git a/docs/compiled/artplayer.legacy.js b/docs/compiled/artplayer.legacy.js index 619727b35..c7316f5ae 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,e=Object.defineProperty,r=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,l=(t,e)=>{for(var r in e||(e={}))i.call(e,r)&&s(t,r,e[r]);if(o)for(var r of o(e))a.call(e,r)&&s(t,r,e[r]);return t},c=(t,e)=>r(t,n(e)),d=(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 u(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var p,h={exports:{}};var f=(p||(p=1,h.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{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new b,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 y?t.push(...e.errors):t.push(e)}if(t.length)throw new y(t)}}const w=new WeakMap,x=new WeakMap;function k(t){const e=w.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function $(t){return k(t).scope}function E(t){const e=k(t);return e.destroying||e.scope.closed}function T(t,e,r,n,o=!1){var i,a,s;const l=k(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof y?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)?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")),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 C=new WeakMap;function L(t,e){const r=$(t).child();return C.set(e,r),r}function S(t){const e=C.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function P(t){var e;null==(e=C.get(t))||e.dispose()}function M(t,e){return{on:(r,n)=>{!function(t,e,r,n){const o=S(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=S(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)}}const z=null!=(t=null==globalThis?void 0:globalThis.CUSTOM_USER_AGENT)?t:"undefined"!==typeof navigator?navigator.userAgent:"",A=/^(?:(?!chrome|android).)*safari/i.test(z),O=/iPad|iPhone|iPod/i.test(z)&&!window.MSStream,R=O||z.includes("Macintosh")&&navigator.maxTouchPoints>=1,I=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(z)||R,_="undefined"!==typeof window&&"undefined"!==typeof document;function N(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function D(t,e=document){return e.querySelector(t)}function W(t,e=document){return Array.from(e.querySelectorAll(t))}function F(t,e){return t.classList.add(e)}function V(t,e){return t.classList.remove(e)}function Y(t,e){return t.classList.contains(e)}function B(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}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){return Array.from(t.parentElement.children).filter(e=>e!==t)}function U(t,e){q(t).forEach(t=>V(t,e)),F(t,e)}function X(t,e,r="top"){I||(t.setAttribute("aria-label",e),F(t,"hint--rounded"),F(t,`hint--${r}`))}function G(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}function K(t,e){return nt(t).includes(e)}function Z(t,e){return e.parentNode.replaceChild(t,e),t}function J(t){return document.createElement(t)}function Q(t="",e=""){const r=J("i");return F(r,"art-icon"),F(r,`art-icon-${t}`),B(r,e),r}function tt(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function et(t){return t.getBoundingClientRect()}function rt(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function nt(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function ot(){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;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class it extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function at(t,e){if(!t)throw new it(e);return t}function st(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function lt(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function ct(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 dt(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function ut(t){return t.charAt(0).toUpperCase()+t.slice(1)}function pt(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 ht={"&":"&","<":"<",">":">","'":"'",'"':"""},ft={"&":"&","<":"<",">":">","'":"'",""":'"'},mt=/(&|<|>|'|")/g;function gt(t){return t.replace(/[&<>'"]/g,t=>ht[t]||t)}const vt=Object.defineProperty,{hasOwnProperty:yt}=Object.prototype;function bt(t,e){return yt.call(t,e)}function wt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function xt(...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)?xt(o,i):i,vt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function kt(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 $t(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function Et(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")}`}function Tt(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}}const Ct=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:it,addClass:F,append:B,assToVtt:Et,capitalize:ut,clamp:dt,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:ct,errorHandle:at,escape:gt,get:wt,getComposedPath:nt,getExt:lt,getIcon:Q,getRect:et,getSafeAreaInsets:ot,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:bt,hasClass:Y,includeFromEvent:K,inverseClass:U,isBrowser:_,isIOS:O,isIOS13:R,isInViewport:G,isMobile:I,isSafari:A,loadImg:rt,mergeDeep:xt,query:D,queryAll:W,remove:function(t){return t.parentNode.removeChild(t)},removeClass:V,replaceElement:Z,secondToTime:pt,setStyle:H,setStyleText:N,setStyles:j,siblings:q,silencePromise:st,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:kt,supportsFlex:tt,throttle:Tt,tooltip:X,unescape:function(t){return t.replace(mt,t=>ft[t]||t)},userAgent:z,vttToBlob:$t},Symbol.toStringTag,{value:"Module"}));function Lt(t,e){return B(t,e)}function St(t,e){return e.querySelector(t)}const Pt="array",Mt="boolean",zt="string",At="number",Ot="object",Rt="function";function It(t,e,r){return at(e===zt||e===At||t instanceof Element,`${r.join(".")} require '${zt}' or 'Element' type`)}const _t={html:It,disable:`?${Mt}`,name:`?${zt}`,index:`?${At}`,style:`?${Ot}`,click:`?${Rt}`,mounted:`?${Rt}`,tooltip:`?${zt}|${At}`,width:`?${At}`,selector:`?${Pt}`,onSelect:`?${Rt}`,switch:`?${Mt}`,onSwitch:`?${Rt}`,range:`?${Pt}`,onRange:`?${Rt}`,onChange:`?${Rt}`},Nt={id:zt,container:It,url:zt,poster:zt,type:zt,theme:zt,lang:zt,volume:At,isLive:Mt,muted:Mt,autoplay:Mt,autoSize:Mt,autoMini:Mt,loop:Mt,flip:Mt,playbackRate:Mt,aspectRatio:Mt,screenshot:Mt,setting:Mt,hotkey:Mt,pip:Mt,mutex:Mt,backdrop:Mt,fullscreen:Mt,fullscreenWeb:Mt,subtitleOffset:Mt,miniProgressBar:Mt,useSSR:Mt,playsInline:Mt,lock:Mt,gesture:Mt,fastForward:Mt,autoPlayback:Mt,autoOrientation:Mt,airplay:Mt,proxy:`?${Rt}`,plugins:[Rt],layers:[_t],contextmenu:[_t],settings:[_t],controls:[c(l({},_t),{position:(t,e,r)=>{const n=["top","left","right"];return at("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${Mt}`,html:zt,url:zt}],highlight:[{time:At,text:zt}],thumbnails:{url:zt,number:At,column:At,width:At,height:At,scale:At},subtitle:{url:zt,name:zt,type:zt,style:Ot,escape:Mt,encoding:zt,onVttLoad:Rt},moreVideoAttr:Ot,i18n:Ot,icons:Ot,cssVar:Ot,customType:Ot},Dt=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 Y(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?F(e,r):V(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(E(this.art))return;const r="function"===typeof t?t(this.art):t;if(E(this.art))return;if(r.html=r.html||"",m(r,_t),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;at(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=L(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){F(t,`art-${r}`),F(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):B(e,t),i.html&&B(t,i.html),i.style&&j(t,i.style),i.tooltip&&X(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{P(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){at(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Dt.has(e)){Dt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{P(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Dt.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 Ft extends Wt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,L(t,this.$parent),I||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=M(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 c(l({},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}=M(e,t),n=D('[data-value="1"]',t);n&&U(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&U(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 c(l({},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}=M(e,t),n=D('[data-value="default"]',t);n&&U(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(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(ut(t))}`).join("");return c(l({},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}=M(e,t),n=D('[data-value="normal"]',t);n&&U(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>c(l({},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 c(l({},t),{html:`ArtPlayer ${g}`})}({name:"version",index:50})),this.add(function(t){return e=>c(l({},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}=et(e),{height:c,width:d}=et(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),j(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{K(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Vt(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 Yt(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 Bt(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)})})}function Ht(t,e){const{$progress:r}=t.template,{left:n}=et(r),o=dt((I?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:pt(i),width:o,percentage:dt(o/r.clientWidth,0,1)}}function jt(t,e){if(t.isRotate){const r=(e.touches[0].clientY-t.top)/t.height,n=r*t.duration;t.emit("setBar","played",r,e),t.seek=n}else{const{second:r,percentage:n}=Ht(t,e);t.emit("setBar","played",n,e),t.seek=r}}function qt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=S(e),{on:a}=M(t,e);let s=()=>{};const l=St(".art-progress-hover",e),c=St(".art-progress-loaded",e),d=St(".art-progress-played",e),u=St(".art-progress-highlight",e),p=St(".art-progress-indicator",e),h=St(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Ht(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?B(p,r.indicator):H(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&I;if("loaded"===r&&H(c,"width",100*n+"%"),"hover"===r&&(H(l,"width",100*n+"%"),K(a,u)?function(r){const{width:n}=Ht(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?H(h,"left",0):n>e.clientWidth-i/2?H(h,"left",e.clientWidth-i+"px"):H(h,"left",n-i/2+"px")}(a):f(a),0===n?V(o,"art-progress-hover"):F(o,"art-progress-hover")),"played"===r&&(H(d,"width",100*n+"%"),H(p,"left",100*n+"%")),m){F(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:pt(n*t.duration)}),s(),s=Yt(i,()=>{V(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 Ut(t){return e=>c(l({},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}=M(t,e);if(!I){let e=!1;i(r,"click",e=>{e.target!==n&&jt(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=Ht(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=Ht(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function Xt(t){const{option:e}=t.art;e.isLive||t.add(Ut({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Lt(t,o.play),s=Lt(t,o.pause);function l(){H(a,"display","flex"),H(s,"display","none")}function c(){H(a,"display","none"),H(s,"display","flex")}X(a,i.get("Play")),X(s,i.get("Pause")),n(a,"click",()=>{st(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=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o}=e,i=Lt(t,o.volume),a=Lt(t,o.volumeClose),s=Lt(t,'
'),l=Lt(s,'
'),c=Lt(l,'
'),d=Lt(l,'
'),u=Lt(d,'
'),p=Lt(u,'
'),h=Lt(d,'
');function f(t){const{top:e,height:r}=et(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)H(i,"display","none"),H(a,"display","flex"),H(h,"top","100%"),H(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;H(i,"display","flex"),H(a,"display","none"),H(h,"top",100-t+"%"),H(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}),I)H(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=>c(l({},t),{style:I?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=M(e,t);function n(){const r=`${pt(e.currentTime)} / ${pt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!$(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!I&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=M(e,t),{icons:n}=e;Lt(t,n.screenshot),r(t,"click",()=>{e.screenshot()})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e;Lt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{X(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e;Lt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{X(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=>c(l({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=M(e,t),{icons:n}=e;Lt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Lt(t,o.fullscreenWebOn),s=Lt(t,o.fullscreenWebOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(X(t,i.get("Exit Web Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(X(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=>c(l({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Lt(t,o.fullscreenOn),s=Lt(t,o.fullscreenOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(X(t,i.get("Exit Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(X(t,i.get("Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rKt.get(t).option.selector}),vt(t,"$control_item",{get:()=>Kt.get(t).item}),vt(t,"$control_value",{get:()=>Kt.get(t).value})),Kt.set(t,e)}function Jt(t,e){t.innerHTML=e}function Qt(t,e,r,n,o){const{proxy:i}=t.events,a=S(n),s=r.selector;F(n,"art-control-selector");const l=document.createElement("div");F(l,"art-selector-value"),B(l,r.html),n.textContent="",B(n,l);const c=Lt(n,'
');for(let d=0;dd(null,null,function*(){if(a.closed)return;const o=nt(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 Gt.set(t,e),()=>{Gt.get(t)===e&&Gt.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()&&Jt(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class te 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;L(t,n);const{on:o}=M(t,n);o("mousemove",()=>{I||(this.show=!0)}),o("click",()=>{I?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=K(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?(V(r,"art-hide-cursor"),F(r,"art-hover"),this.timer=Date.now()):(F(r,"art-hide-cursor"),V(r,"art-hover"))}),this.init(),$(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=S(e),{on:i}=M(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(){Xt(this)}add(t){if(E(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:at(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Jt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function ee(t,e,r,n){const o=e-n,i=r-t;let a=0;if(Math.abs(i)<2&&Math.abs(o)<2)return a;const s=function(t,e){return 180*Math.atan2(e,t)/Math.PI}(i,o);return s>=-45&&s<45?a=4:s>=45&&s<135?a=1:s>=-135&&s<-45?a=2:(s>=135&&s<=180||s>=-180&&s<-135)&&(a=3),a}function re(t){if(t.constructor.USE_RAF){const e=$(t);let r=()=>{};!function n(){t.playing&&t.emit("raf"),t.isDestroy||(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))}(),t.on("destroy",()=>{r()})}}const ne=new WeakMap;class oe{constructor(t){this.destroyEvents=new Set;const e=$(t);ne.set(this,e),e.add(()=>this.destroy()),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),function(t,e){const{constructor:r,template:{$player:n,$video:o}}=t;function i(e){K(e,n)?(t.isInput="INPUT"===e.target.tagName,t.isFocus=!0,t.emit("focus",e)):(t.isInput=!1,t.isFocus=!1,t.emit("blur",e))}t.on("document:click",i),t.on("document:contextmenu",i);let a=[];e.proxy(o,"click",e=>{const n=Date.now();a.push(n);const{MOBILE_CLICK_PLAY:o,DBCLICK_TIME:i,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=a.filter(t=>n-t<=i);switch(c.length){case 1:t.emit("click",e),I?!t.isLock&&o&&st(t.toggle()):st(t.toggle()),a=c;break;case 2:t.emit("dblclick",e),I?!t.isLock&&s&&st(t.toggle()):l&&(t.fullscreen=!t.fullscreen),a=[];break;default:a=[]}})}(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{F(r,"art-hover"),t.emit("hover",!0,e)},e=>{V(r,"art-hover"),t.emit("hover",!1,e)})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t;t.on("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),t.aspectRatio=e,n.show=""});const o=$(t);let i=()=>{};const a=()=>{i(),i=Yt(o,()=>t.emit("resize"),n.RESIZE_TIME)};t.on("window:orientationchange",()=>a()),t.on("window:resize",()=>a()),screen&&screen.orientation&&screen.orientation.onchange&&e.proxy(screen.orientation,"change",()=>a())}(t,this),function(t,e){if(I&&!t.option.isLive){const{$video:r,$progress:n}=t.template;let o=null,i=!1,a=0,s=0,l=0;const c=e=>{if(1===e.touches.length&&!t.isLock){o===n&&jt(t,e),i=!0;const{pageX:r,pageY:c}=e.touches[0];a=r,s=c,l=t.currentTime}},d=e=>{if(1===e.touches.length&&i&&t.duration){const{pageX:n,pageY:i}=e.touches[0],c=ee(a,s,n,i),d=[3,4].includes(c),u=[1,2].includes(c);if(d&&!t.isRotate||u&&t.isRotate){const c=dt((n-a)/t.width,-1,1),d=dt((i-s)/t.height,-1,1),u=t.isRotate?d:c,p=o===r?t.constructor.TOUCH_MOVE_RATIO:1,h=dt(l+t.duration*u*p,0,t.duration);t.seek=h,t.emit("setBar","played",dt(h/t.duration,0,1),e),t.notice.show=`${pt(h)} / ${pt(t.duration)}`}}},u=()=>{i&&(a=0,s=0,l=0,i=!1,o=null)};t.option.gesture&&(e.proxy(r,"touchstart",t=>{o=r,c(t)}),e.proxy(r,"touchmove",d)),e.proxy(n,"touchstart",t=>{o=n,c(t)}),e.proxy(n,"touchmove",d),t.on("document:touchend",u)}}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=Tt(()=>{t.emit("view",G(n,r.SCROLL_GAP))},r.SCROLL_TIME);t.on("window:scroll",()=>o()),t.on("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){const r=["click","mouseup","keydown","touchend","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],n=["resize","scroll","orientationchange"],o=[];function i(i={}){for(let t=0;t{const n=i.document||a.ownerDocument||document,s=e.proxy(n,r,e=>{t.emit(`document:${r}`,e)});o.push(s)}),n.forEach(r=>{var n;const s=i.window||(null==(n=a.ownerDocument)?void 0:n.defaultView)||window,l=e.proxy(s,r,e=>{t.emit(`window:${r}`,e)});o.push(l)})}i(),e.bindGlobalEvents=i}(t,this),re(t)}proxy(t,e,r,n={}){if(Array.isArray(e))return e.map(e=>this.proxy(t,e,r,n));if(ne.get(this).closed)return()=>{};t.addEventListener(e,r,n);const o=()=>t.removeEventListener(e,r,n);return this.destroyEvents.add(o),o}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){if(this.destroyEvents.has(t))try{t()}catch(e){console.warn("Failed to remove event listener:",e)}finally{this.destroyEvents.delete(t)}}destroy(){for(const e of this.destroyEvents)try{e()}catch(t){console.warn("Failed to destroy event listener:",t)}this.destroyEvents.clear()}}class ie{constructor(t){this.art=t,this.keys={},I||this.init()}init(){const{constructor:t}=this.art;this.art.option.hotkey&&(this.add("Escape",()=>{this.art.fullscreenWeb&&(this.art.fullscreenWeb=!1)}),this.add("Space",()=>{st(this.art.toggle())}),this.add("ArrowLeft",()=>{this.art.backward=t.SEEK_STEP}),this.add("ArrowUp",()=>{this.art.volume+=t.VOLUME_STEP}),this.add("ArrowRight",()=>{this.art.forward=t.SEEK_STEP}),this.add("ArrowDown",()=>{this.art.volume-=t.VOLUME_STEP})),this.art.on("document:keydown",t=>{if(this.art.isFocus){const e=document.activeElement.tagName.toUpperCase(),r=document.activeElement.getAttribute("contenteditable");if("INPUT"!==e&&"TEXTAREA"!==e&&""!==r&&"true"!==r&&!t.altKey&&!t.ctrlKey&&!t.metaKey&&!t.shiftKey){const e=this.keys[t.code];if(e){t.preventDefault();for(let r=0;r\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 ce{constructor(t){const e=l(l({},le),t.option.icons);for(const r in e)vt(this,r,{get:()=>Q(r,e[r])})}}class de extends Wt{constructor(t){super(t),this.name="info",I||this.init()}init(){const{proxy:t,constructor:e,template:{$infoPanel:r,$infoClose:n,$video:o}}=this.art;t(n,"click",()=>{this.show=!1});let i=()=>{};const a=W("[data-video]",r)||[];this.art.on("destroy",()=>i());const s=$(this.art);!function t(){for(let e=0;e{H(o,"display","none"),H(i,"display",null)}),n.proxy(e.$state,"click",()=>st(t.play()))}}class fe{constructor(t){this.art=t,this.timer=null,$(t).add(()=>this.destroy()),t.on("destroy",()=>this.destroy())}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}set show(t){if($(this.art).closed)return;const{constructor:e,template:{$player:r,$noticeInner:n}}=this.art;t?(n.textContent=t instanceof Error?t.message.trim():t,F(r,"art-notice-show"),clearTimeout(this.timer),this.timer=setTimeout(()=>{n.textContent="",V(r,"art-notice-show")},e.NOTICE_TIME)):V(r,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function me({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function ge(t,e){if(!me(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 me(r)?r:void 0}function ve(t){const{$container:e,$video:r}=t.template;vt(t,"autoHeight",{value(){if(E(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!me(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||E(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function ye(t,e,r,n=!1){const o=e=>{E(t)||r(e)};t[n?"once":"on"](e,o),$(t).add(()=>{t.off(e,o)})}function be(t,e,r){for(const[n,o]of e){if(E(t)||r&&!r())return;t[n].show=o}}const we=new WeakMap,xe=new WeakMap,ke=new WeakMap;function $e(t){return ke.get(t)||$(t)}function Ee(t){const e=we.get(t),r=ke.get(t);return()=>we.get(t)===e&&(!e||e.active())&&ke.get(t)===r&&(!r||!r.closed)}function Te(t){const e=ke.get(t),r=$(t).child(),n=r.child();ke.set(t,r),r.add(()=>{ke.get(t)===r&&ke.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!E(t)&&!n.closed&&we.get(t)===o};return we.set(t,o),n.add(()=>{we.get(t)===o&&we.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function Ce(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function Le(t,e,r){xe.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{xe.get(t)===e&&(xe.delete(t),Ce(e))}}function Se(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Pe(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=$e(t),l=0;return{reset(){l=0,null==a||a.dispose(),V(i,"art-error")},loadStart(){V(i,"art-error")},schedule(c){(c=>d(null,null,function*(){if(E(t))return;const d=$e(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!E(t)&&!u.closed&&d===$e(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Me(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{E(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Pe(t);!function(t,e){ye(t,"video:canplay",()=>{e.reset(),be(t,[["loading",!1]])}),ye(t,"video:canplay",()=>{be(t,[["loading",!1],["controls",!0],["mask",!0]]),E(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;ye(t,"video:ended",()=>{if(e.loop){const e=Ee(t);if(t.seek=0,E(t)||!e())return;st(t.play()),e()&&be(t,[["controls",!1],["mask",!1]],e)}else be(t,[["controls",!0],["mask",!0]])})}(t),ye(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;ye(t,"video:loadedmetadata",()=>{t.emit("resize"),I&&be(t,[["loading",!1],["controls",!0],["mask",!0]])}),ye(t,"video:loadstart",()=>{e.loadStart(),be(t,[["loading",!0],["mask",!1],["controls",!0]])}),ye(t,"video:pause",()=>{be(t,[["controls",!0],["mask",!0]])}),ye(t,"video:play",()=>{be(t,[["mask",!1]]),E(t)||H(r,"display","none")}),ye(t,"video:playing",()=>be(t,[["mask",!1]])),ye(t,"video:progress",()=>{t.playing&&be(t,[["loading",!1]])}),ye(t,"video:seeked",()=>be(t,[["loading",!1],["mask",!0]])),ye(t,"video:seeking",()=>be(t,[["loading",!0],["mask",!1]])),ye(t,"video:timeupdate",()=>be(t,[["mask",!1]])),ye(t,"video:waiting",()=>be(t,[["loading",!0],["mask",!1]]))}(t,e)}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})(),Oe={change:Ae.fullscreenchange,error:Ae.fullscreenerror},Re={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Re.off("change",o),r()};Re.on("change",o);const i=t[Ae.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Re.isFullscreen)return void t();const r=()=>{Re.off("change",r),t()};Re.on("change",r);const n=document[Ae.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Re.isFullscreen?Re.exit():Re.request(t,e),onchange(t){Re.on("change",t)},onerror(t){Re.on("error",t)},on(t,e){const r=Oe[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Oe[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(Re,{isFullscreen:{get:()=>Boolean(document[Ae.fullscreenElement])},element:{enumerable:!0,get:()=>document[Ae.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Ae.fullscreenEnabled])}});const _e=new WeakMap;function Ne(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function De(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=_e.get(t);if(!n){n=new WeakMap,_e.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Ne(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Ne(i))}function We(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&&De(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Vt(i,t.document,t.changeEvent,m),Vt(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=_e.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&&De(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 Fe(t,e){const r=$(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()}),Vt(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=_e.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||E(t))return;s=r;const o=l,a=()=>E(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")))}),Vt(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!E(t)&&t.emit("fullscreenError",r)}),{get:()=>!E(t)&&i(),set(n){if(E(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=We(e,r,c,()=>{!E(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw E(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){var e;if(Ve.has(this)&&Ye(this,"webkitbeginfullscreen"===t.type)){Be(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function je(t){Ve.add(t),t.addEventListener("webkitbeginfullscreen",He),t.addEventListener("webkitpresentationmodechanged",He)}function qe(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=Ye(e),i=o,a=!1,s=0;const l=()=>Ye(e,n);function c(r){if(E(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 u=s,p=()=>E(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&&je(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Vt(r,e,"webkitbeginfullscreen",()=>c(!0)),Vt(r,e,"webkitendfullscreen",()=>c(!1)),Vt(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!E(t)&&l(),set(r){if(E(t))return;const n=++s;if(i=Boolean(r),r){if(Be(e),t.state="fullscreen",E(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){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(E(t))return;const i=function(t){const e=Re.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?vt(t,"fullscreen",Fe(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?vt(t,"fullscreen",qe(t)):vt(t,"fullscreen",{get:()=>!1,set(){E(t)||(r.show=e.get("Fullscreen Not Supported"))}}),vt(t,"fullscreen",wt(t,"fullscreen"))};t.once("video:loadedmetadata",i),$(t).add(()=>{t.off("video:loadedmetadata",i)})}function Xe(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Ge({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 Ke(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()&&(Ge(t.placement),r()))}return $(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 y([a,s])}throw a}}),i=>{if(E(t))return;const a=++n,s=()=>a===n&&!E(t);if(i){r||(r={placement:Xe(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);vt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function Ze(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 Je(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Qe(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),Vt(o,e,"click",n),Vt(o,l,"click",()=>{st(t.play())}),Vt(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=""};Vt(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=Ze(i.left,i.top,Je(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 tr(t){const{$player:e,$video:r}=t.template,n=$(t).child();let o,i,a=0,s=!1,d=!1;const u=()=>!E(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{Ge(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(E(t))return;const r=++a;d=!1,p(),E(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(E(t))return;const m=++a;if(s)d=!0;else if(t.state="mini",!E(t)&&m===a){null!=i||(i=Xe(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Qe(t,n,u,h)}finally{s=!1}}if(d)return d=!1,void f();if(!o||E(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),E(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}:c(l({},Ze(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,Je(o.element));if(E(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),E(t)||m!==a)return;t.storage.set("left",i.left)}E(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,E(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 er=new WeakSet,rr=t=>"picture-in-picture"===t.webkitPresentationMode;function nr(t){er.delete(t),t.removeEventListener("webkitpresentationmodechanged",or),t.removeEventListener("enterpictureinpicture",or)}function or(){var t;if(er.has(this)&&rr(this)){nr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function ir(t){er.add(t),t.addEventListener("webkitpresentationmodechanged",or),t.addEventListener("enterpictureinpicture",or)}function ar(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=$(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||!E(t)&&a||d()},e=>{E(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Vt(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!E(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Vt(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!E(t)&&o()?e:null,set(n){if(E(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",E(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=$(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(E(t)||er.has(e))return;const s=rr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),E(t)||i!==l||rr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&ir(e),rr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Vt(r,e,l,()=>s());return{get:()=>!E(t)&&rr(e),set(r){var n;if(E(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(nr(e),t.state="pip",E(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,ir(e)),rr(e)&&e.webkitSetPresentationMode("inline");E(t)||l!==i||c!==a||rr(e)!==Boolean(r)||s(!0)}}}(t)):vt(t,"pip",{get:()=>!1,set(){E(t)||(r.show=e.get("PIP Not Supported"))}})}function sr(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 d(this,null,function*(){const r=function(t){return t&&Gt.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!E(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!E(t)&&r()&&(n.show=i)}return e.html})}})}})}function lr(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 cr(t,e,r){return new Promise((n,o)=>{if(E(t)||e===t.url)return void n();const i=Te(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(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child(),h={"video:error":u,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){u(e)}},"video:canplay":()=>{if(!c())return;p.dispose();d(null,null,function*(){if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{yield t.play()}catch(e){}c()&&(t.notice.show="",l())}}).catch(u)}},f=a.child(),m=[],g=Object.keys(h);for(const e of g)lr(f,t,e,t=>{i.acceptingEvents&&m.push([e,t])},!1);if(Le(t,i,e),!c())return;if(t.notice.show="",!c())return;const v=()=>{if(f.dispose(),!e)return void l();const r={};for(const e of g)r[e]=lr(p,t,e,h[e]);for(const[t,e]of m){if(!c()||p.closed)break;r[t](e)}m.length=0};i.assigned?v():i.onAssigned=v}catch(p){u(p)}})}function dr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",(o,s,l)=>d(null,null,function*(){var c;const d=null==(c=t.controls)?void 0:c.thumbnails,{url:u,scale:p}=e.thumbnails;if(!d||!u)return;if("hover"===o||"played"===o&&l&&I){if(a||i||(i=!0,a=yield rt(u,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-h/2?H(s,"left",r.clientWidth-h+"px"):H(s,"left",o-h/2+"px")}(o)}})),vt(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function ur(t){const{option:e,template:{$video:r}}=t;vt(t,"url",{get:()=>r.src,set(n){return d(this,null,function*(){if(E(t))return;const o=function(t){const e=xe.get(t);return xe.delete(t),e||Te(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield Bt(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||lt(n),s=e.customType[a];if(a&&s){if(!(yield Bt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;lr(l,t,"video:canplay",()=>{c=!d}),lr(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=>Se(o,t))}else{if(i&&URL.revokeObjectURL(i),!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||lr(o.scope,t,"video:canplay",e)}}catch(i){Se(o,i)}finally{Ce(o)}})}})}class pr{constructor(t){ur(t),function(t){const{template:{$video:e}}=t;vt(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;vt(t,"play",{value(){return d(this,null,function*(){const a=Ee(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()})}(t),function(t){const{notice:e}=t;vt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${pt(t.currentTime)} / ${pt(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}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;vt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=dt(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)}})}(t),function(t){const{$video:e}=t.template;vt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=dt(n,0,t.duration))}})}(t),function(t){vt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>cr(t,e,0);vt(t,"switchQuality",{value:e=>cr(t,e,t.currentTime)}),vt(t,"switchUrl",{value:e}),vt(t,"switch",{set:e})}(t),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}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;vt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!E(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=ge({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(E(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}`,E(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=J("canvas");vt(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),vt(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),vt(t,"screenshot",{value:e=>d(null,null,function*(){const n=yield t.getDataURL();return ct(n,`${e||`artplayer_${pt(r.currentTime)}`}.png`),t.emit("screenshot",n),n})})}(t),Ue(t),Ke(t),ar(t),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})}(t),function(t){vt(t,"played",{get:()=>t.currentTime/t.duration})}(t),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)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;vt(t,"autoSize",{value(){if(E(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!me(o))return;const i=et(e),a=ge(i,o.width/o.height);a&&!E(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}))}})}(t),function(t){const e=t;vt(t,"rect",{get:()=>et(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})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;vt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){E(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(ut(o))}`,E(t)||t.emit("flip",o))}})}(t),function(t){vt(t,"mini",tr(t))}(t),function(t){const{template:{$poster:e}}=t;vt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){H(e,"backgroundImage",`url(${t})`)}})}(t),ve(t),function(t){const{$player:e}=t.template;vt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){vt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){vt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),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{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,vt(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),sr(t),dr(t),Me(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=dt(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=dt(i,0,1)),e.poster&&H(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const hr=new WeakMap,fr="art-auto-orientation-fullscreen";function mr(t){if(hr.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const gr="art-auto-orientation",vr=["width","height","transform-origin","transform"];function yr(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 me(t)&&me(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=$(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(gr);r.classList.remove(gr),n&&(t.isRotate=!1,E(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=ot();if(E(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=vr.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(gr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;E(t)||(r?o?s(!1):e()&&(i(),i=Yt(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(fr),t&&(t.cancelled=!0,mr(t),t.settled&&hr.get(t.orientation)===t&&hr.delete(t.orientation))}return $(t).add(o),i=>{var a,s;if(E(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=()=>!E(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(fr),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(fr):(mr(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),$(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function br(t){const{i18n:e,icons:r,storage:n,constructor:o,proxy:i,template:{$poster:a}}=t,s=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '}),l=D(".art-auto-playback-last",s),c=D(".art-auto-playback-jump",s),d=D(".art-auto-playback-close",s);B(d,r.close);let u=null;function p(){const r=(n.get("times")||{})[t.option.id||t.option.url];clearTimeout(u),H(s,"display","none"),r&&r>=o.AUTO_PLAYBACK_MIN&&(H(s,"display","flex"),l.textContent=`${e.get("Last Seen")} ${pt(r)}`,c.textContent=e.get("Jump Play"),i(d,"click",()=>{H(s,"display","none")}),i(c,"click",()=>{t.seek=r,st(t.play()),H(a,"display","none"),H(s,"display","none")}),t.once("video:timeupdate",()=>{u=setTimeout(()=>{H(s,"display","none")},o.AUTO_PLAYBACK_TIMEOUT)}))}return t.on("video:timeupdate",()=>{if(t.playing){const e=n.get("times")||{},r=Object.keys(e);r.length>o.AUTO_PLAYBACK_MAX&&delete e[r[0]],e[t.option.id||t.option.url]=t.currentTime,n.set("times",e)}}),t.on("ready",p),t.on("restart",p),{name:"auto-playback",get times(){return n.get("times")||{}},clear:()=>n.del("times"),delete(t){const e=n.get("times")||{};return delete e[t],n.set("times",e),e}}}function wr(t){const{constructor:e,proxy:r,template:{$player:n,$video:o}}=t;let i=null,a=!1,s=1;const l=()=>{clearTimeout(i),a&&(a=!1,t.playbackRate=s,V(n,"art-fast-forward"))};return r(o,"touchstart",r=>{1===r.touches.length&&t.playing&&!t.isLock&&(i=setTimeout(()=>{a=!0,s=t.playbackRate,t.playbackRate=e.FAST_FORWARD_VALUE,F(n,"art-fast-forward")},e.FAST_FORWARD_TIME))}),t.on("document:touchmove",l),t.on("document:touchend",l),{name:"fastForward",get state(){return Y(n,"art-fast-forward")}}}function xr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return Y(n,"art-lock")}function i(){F(n,"art-lock"),t.isLock=!0,t.emit("lock",!0)}function a(){V(n,"art-lock"),t.isLock=!1,t.emit("lock",!1)}return e.add({name:"lock",mounted(e){const n=B(e,r.lock),o=B(e,r.unlock);H(n,"display","none"),t.on("lock",t=>{t?(H(n,"display","inline-flex"),H(o,"display","none")):(H(n,"display","none"),H(o,"display","inline-flex"))})},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function kr(t){return t.on("control",e=>{e?V(t.template.$player,"art-mini-progress-bar"):F(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class $r{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){E(t.art)||!e.miniProgressBar||e.isLive||t.add(kr),!E(t.art)&&e.lock&&I&&t.add(xr),E(t.art)||!e.autoPlayback||e.isLive||t.add(br),!E(t.art)&&e.autoOrientation&&I&&t.add(yr),!E(t.art)&&e.fastForward&&I&&!e.isLive&&t.add(wr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){at(!E(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(E(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(E(t.art))return t;let o=n;const i=bt(t,o);if(E(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return E(t.art)||(at(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),E(t.art)||vt(t,o,{value:r})),t}(this,t,e)}}const Er=new WeakMap;function Tr(t){return!t.closed&&!Er.get(t)}function Cr(t){Er.set(t,(Er.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Er.get(t)||1)-1;r?Er.set(t,r):Er.delete(t)}}const Lr=new WeakMap,Sr=new WeakMap,Pr=["$parent","$parents","$option","$events","$formatted"];function Mr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Lr.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=Lr.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function zr(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 Ar(t){const e=Lr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Or(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>Fr(t,o)])try{e()}catch(d){d instanceof y?l.push(...d.errors):l.push(d)}if(r.closed||E(t)||(o.push(...i.splice(0)),Wr.set(r,o),Nr.set(e,r),Dr.set(e,n)),a(),l.length)throw new y(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function jr(t,e,r,n,o,i){const a=i||Yr(e);if(!Tr(a)||E(t))return;const s=t.proxy(r,n,e=>{if(Tr(a)&&!E(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Tr(a)||E(t)?t.events.remove(s):(Ar(e).events.push(s),i&&i!==Nr.get(e)&&i.add(()=>{const r=Ar(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function qr(t,e,r,n){const o=Yr(e);if(!Tr(o)||E(t))return;const i=(...e)=>{if(Tr(o)&&!E(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Ur(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||I||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const Xr=new WeakMap;function Gr(t){Xr.delete(t)}const Kr=new WeakMap;function Zr(t,e){e?Kr.set(t,e):Kr.delete(t)}function Jr(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=Kr.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(),Zr(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 Qr=new WeakMap;function tn(t,e,r,n,o,i,a,s){return d(this,null,function*(){try{const l=Yr(e),c=Yr(i),d=(Qr.get(i)||0)+1;Qr.set(i,d);const u=()=>Tr(l)&&Tr(c)&&!E(t.art)&&Qr.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 en(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 nn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof y?e.push(...r.errors):e.push(r)}if(e.length)throw new y(e)}function on(t){var e;null==(e=rn.get(t))||e()}function an(t,e){const r=t.find(e.name);if(E(t.art))return r||e;if(!r)return t.add(e);Gr(r),on(r);const n=Jr(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?en(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=Hr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Cr(Ir(t)))}catch(l){try{nn([...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,nn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,nn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>_r(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)rn.get(t)===h&&rn.delete(t);if(E(t.art))return void d.dispose();const e=r.$item;try{nn([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)&&U(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&&!E(t.art)&&rn.get(r)===h;for(const v of d.items)rn.set(v,h);const m=$(t.art).add(()=>{u=!1;for(const t of d.items)rn.get(t)===h&&rn.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)rn.get(t)===h&&rn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const sn=new WeakMap;function ln(t,e,r){vt(t,`$${e}`,{configurable:!0,get:()=>r}),vt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",B(r,t)}})}function cn(t,e,r=!1){var n,o;const i=function(t){const e=rn.get(t);return()=>!e||rn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";bt(e,"switch")&&(l="switch"),bt(e,"range")&&(l="range"),bt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=$(t)){const n=Nr.get(e);(!n||Tr(n)||n.closed)&&Br(t,e);const o=r.child();return Nr.set(e,o),Dr.set(e,r),Wr.set(o,Ar(e).events),o.add(()=>{Fr(t,Wr.get(o))}),o}(t.art,e,Ir(a)),p=()=>Tr(u)&&!E(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(Zr(e),F(h,"art-setting-item"),H(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=B(h,'
'),f=B(h,'
'),m=document.createElement("div");switch(F(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;B(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;B(m,t)}else B(m,c.check)}if(B(i,m),!p())return;ln(e,"icon",m);const g=document.createElement("div");F(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;B(g,v),B(i,g),ln(e,"html",g);const y=document.createElement("div");F(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(B(y,b),B(f,y),ln(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");F(t,"art-setting-item-right-icon");const r=B(t,c.switchOn),n=B(t,c.switchOff),o=e.switch;if(!p())return;H(o?n:r,"display","none"),B(f,t),vt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;Zr(e,()=>{const t=i;return()=>{i=t}}),vt(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");F(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",B(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))}F(r,"art-setting-range"),B(f,t),vt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;Zr(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");F(t,"art-setting-item-right-icon"),B(t,c.arrowRight),B(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=Yr(e),a=(t,r,n)=>jr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>tn(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=>tn(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 tn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&F(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>tn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,h,l),!p())return;vt(e,"$item",{configurable:!0,get:()=>h}),r&&(null==s?void 0:s.parentNode)?s.replaceWith(h):B(a,h),e.mounted&&p()&&Yt(u,()=>{var r;if(!E(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 dn(t,e=t.option){var r;if(E(t.art))return;const n=t.cache.get(e);if(n&&!Tr(Ir(n)))return;const o=(sn.get(t)||0)+1;sn.set(t,o);const i=()=>sn.get(t)===o&&!E(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)&&U(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{U(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Ir(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=$(t.art).child();return Rr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!E(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;F(n,"art-setting-panel"),B(t.$parent,n),U(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Sr.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=$(e).child(),n=(t,n)=>{if(r.closed||E(e))return;const o=(...t)=>{if(!r.closed&&!E(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=K(r,e.controls.setting),o=K(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||E(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(),qr(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(),qr(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(ut(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(),qr(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)=>{qr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Or(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&&U(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=Sr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;oAr(t).parent},$parents:{get:()=>Ar(t).parents},$option:{get:()=>Ar(t).option},$events:{get:()=>Ar(t).events},$formatted:{get:()=>!0}}),Lr.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 Or(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){Ur(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&&_r(n)}catch(i){r.push(i)}}try{Br(t.art,e)}catch(i){i instanceof y?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new y(r)}(this,t)}remove(t){const e=this.find(t);at(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Gr(t),on(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 y?o.push(...i.errors):o.push(i)}if(o.length)throw new y(o)}update(t){return an(this,t)}add(t,e=this.option){var r;if(E(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={};Xr.set(t,e);const r=()=>Xr.get(t)===e;return{current:r,finish(){r()&&Xr.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(E(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");H(i,"height",`${o}px`),F(i,"art-setting-item"),F(i,"art-setting-item-back");const a=B(i,'
'),s=document.createElement("div");F(s,"art-setting-item-left-icon"),B(s,n),B(a,s),B(a,e.$parent.html),jr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Ir(r)),B(r,i)}(this,t)}createItem(t,e=!1){cn(this,t,e)}render(t=this.option){dn(this,t)}}class hn{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 fn='.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 mn{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 d(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const gn=new WeakMap;function vn(t){return gn.get(t)}function yn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const bn=Wt;class wn extends bn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=$(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return gn.set(t,n),r.add(()=>{yn(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?j(r,t):H(r,t,e)}update(){!function(t){const e=vn(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?gt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return d(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=c(l(l({},o.subtitle),e),{url:t}),a=vn(this),s=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=vn(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&&yn(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 d(this,null,function*(){const e=vn(this),r=function(t){const e=t.request,r=new mn(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(()=>d(this,null,function*(){if(!this.textTrack)return null;if(m(t,Nt.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||lt(e.url)){case"srt":return{vtt:e.onVttLoad(kt(r))};case"ass":return{vtt:e.onVttLoad(Et(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=$t(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 xn=`\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
${g}
\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 kn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=D(e.container),at(this.$container,`No container element found by ${e.container}`)),at(tt(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();at("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),at(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=x.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=k(t);o.rollback=r,x.set(e,t),o.releaseContainer=()=>{x.get(e)===t&&x.delete(e)}}(t,this.$container,en(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return xn}query(t){return D(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=kn.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);!function(t){at(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&&F(this.$player,"art-backdrop"),I&&F(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":F(this.$player,"art-destroy")}}const $n=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class En{on(t,e,r){const n=this.e||(this.e={});let o=$n(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=($n(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=$n(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;ie.call(this,this)),Ln.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Ln.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=k(t);return e.rollback=void 0,!e.scope.closed})(this)&&Cn.push(this)}catch(n){try{T(this,Cn,!0,Ln.REMOVE_SRC_WHEN_DESTROY,!0)}catch(o){console.warn("Failed to clean up ArtPlayer initialization:",o)}throw n}}static get instances(){return Cn}static get version(){return g}static get config(){return v}static get utils(){return Ct}static get scheme(){return Nt}static get Emitter(){return En}static get validator(){return m}static get kindOf(){return m.kindOf}static get html(){return kn.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:A?"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){T(this,Cn,t,Ln.REMOVE_SRC_WHEN_DESTROY)}}return Ln.STYLE=fn,Ln.DEBUG=!1,Ln.CONTEXTMENU=!0,Ln.NOTICE_TIME=2e3,Ln.SETTING_WIDTH=250,Ln.SETTING_ITEM_WIDTH=200,Ln.SETTING_ITEM_HEIGHT=35,Ln.RESIZE_TIME=200,Ln.SCROLL_TIME=200,Ln.SCROLL_GAP=50,Ln.AUTO_PLAYBACK_MAX=10,Ln.AUTO_PLAYBACK_MIN=5,Ln.AUTO_PLAYBACK_TIMEOUT=3e3,Ln.RECONNECT_TIME_MAX=5,Ln.RECONNECT_SLEEP_TIME=1e3,Ln.CONTROL_HIDE_TIME=3e3,Ln.DBCLICK_TIME=300,Ln.DBCLICK_FULLSCREEN=!0,Ln.MOBILE_DBCLICK_PLAY=!0,Ln.MOBILE_CLICK_PLAY=!1,Ln.AUTO_ORIENTATION_TIME=200,Ln.INFO_LOOP_TIME=1e3,Ln.FAST_FORWARD_VALUE=3,Ln.FAST_FORWARD_TIME=1e3,Ln.TOUCH_MOVE_RATIO=.5,Ln.VOLUME_STEP=.1,Ln.SEEK_STEP=5,Ln.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Ln.ASPECT_RATIO=["default","4:3","16:9"],Ln.FLIP=["normal","horizontal","vertical"],Ln.FULLSCREEN_WEB_IN_BODY=!0,Ln.LOG_VERSION=!0,Ln.USE_RAF=!1,Ln.REMOVE_SRC_WHEN_DESTROY=!0,_&&(window.Artplayer=Ln,N("artplayer-style",fn),setTimeout(()=>{Ln.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Ln.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Ln}); +!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,e=Object.defineProperty,r=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,l=(t,e)=>{for(var r in e||(e={}))i.call(e,r)&&s(t,r,e[r]);if(o)for(var r of o(e))a.call(e,r)&&s(t,r,e[r]);return t},c=(t,e)=>r(t,n(e)),d=(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 u(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var p,h={exports:{}};var f=(p||(p=1,h.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{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new b,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 y?t.push(...e.errors):t.push(e)}if(t.length)throw new y(t)}}const w=new WeakMap,x=new WeakMap;function k(t){const e=w.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function $(t){return k(t).scope}function E(t){const e=k(t);return e.destroying||e.scope.closed}function T(t,e,r,n,o=!1){var i,a,s;const l=k(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof y?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)?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")),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 C=new WeakMap;function L(t,e){const r=$(t).child();return C.set(e,r),r}function S(t){const e=C.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function P(t){var e;null==(e=C.get(t))||e.dispose()}function M(t,e){return{on:(r,n)=>{!function(t,e,r,n){const o=S(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=S(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)}}const z=null!=(t=null==globalThis?void 0:globalThis.CUSTOM_USER_AGENT)?t:"undefined"!==typeof navigator?navigator.userAgent:"",A=/^(?:(?!chrome|android).)*safari/i.test(z),O=/iPad|iPhone|iPod/i.test(z)&&!window.MSStream,R=O||z.includes("Macintosh")&&navigator.maxTouchPoints>=1,I=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(z)||R,_="undefined"!==typeof window&&"undefined"!==typeof document;function N(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function D(t,e=document){return e.querySelector(t)}function F(t,e=document){return Array.from(e.querySelectorAll(t))}function W(t,e){return t.classList.add(e)}function V(t,e){return t.classList.remove(e)}function Y(t,e){return t.classList.contains(e)}function B(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function j(t,e,r){return t.style[e]=r,t}function H(t,e){for(const r in e)j(t,r,e[r]);return t}function q(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function U(t,e){q(t).forEach(t=>V(t,e)),W(t,e)}function X(t,e,r="top"){I||(t.setAttribute("aria-label",e),W(t,"hint--rounded"),W(t,`hint--${r}`))}function G(t,e){return rt(t).includes(e)}function K(t,e){return e.parentNode.replaceChild(t,e),t}function Z(t){return document.createElement(t)}function J(t="",e=""){const r=Z("i");return W(r,"art-icon"),W(r,`art-icon-${t}`),B(r,e),r}function Q(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function tt(t){return t.getBoundingClientRect()}function et(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function rt(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function nt(){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;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}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:W,append:B,assToVtt:$t,capitalize:dt,clamp:ct,createElement:Z,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:rt,getExt:st,getIcon:J,getRect:tt,getSafeAreaInsets:nt,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:Y,includeFromEvent:G,inverseClass:U,isBrowser:_,isIOS:O,isIOS13:R,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:I,isSafari:A,loadImg:et,mergeDeep:wt,query:D,queryAll:F,remove:function(t){return t.parentNode.removeChild(t)},removeClass:V,replaceElement:K,secondToTime:ut,setStyle:j,setStyleText:N,setStyles:H,siblings:q,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:Q,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:X,unescape:function(t){return t.replace(ft,t=>ht[t]||t)},userAgent:z,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function Tt(t,e){return B(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:[c(l({},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},_t=new WeakSet;class Nt{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 Y(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?W(e,r):V(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(E(this.art))return;const r="function"===typeof t?t(this.art):t;if(E(this.art))return;if(r.html=r.html||"",m(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=L(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){W(t,`art-${r}`),W(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):B(e,t),i.html&&B(t,i.html),i.style&&H(t,i.style),i.tooltip&&X(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{P(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(!_t.has(e)){_t.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{P(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{_t.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 Dt extends Nt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,L(t,this.$parent),I||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=M(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 c(l({},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}=M(e,t),n=D('[data-value="1"]',t);n&&U(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&U(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 c(l({},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}=M(e,t),n=D('[data-value="default"]',t);n&&U(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(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 c(l({},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}=M(e,t),n=D('[data-value="normal"]',t);n&&U(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>c(l({},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 c(l({},t),{html:`ArtPlayer ${g}`})}({name:"version",index:50})),this.add(function(t){return e=>c(l({},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}=tt(e),{height:c,width:d}=tt(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),H(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{G(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Ft(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 Wt(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)})})}function Yt(t,e){const{$progress:r}=t.template,{left:n}=tt(r),o=ct((I?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 Bt(t,e,r=()=>!0){if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Yt(t,e);t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function jt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=S(e),{on:a}=M(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||Yt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?j(h,"left",0):o>e.clientWidth-a/2?j(h,"left",e.clientWidth-a+"px"):j(h,"left",o-a/2+"px")}r.indicator?B(p,r.indicator):j(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&I;if("loaded"===r&&j(c,"width",100*n+"%"),"hover"===r&&(j(l,"width",100*n+"%"),G(a,u)?function(r){const{width:n}=Yt(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?j(h,"left",0):n>e.clientWidth-i/2?j(h,"left",e.clientWidth-i+"px"):j(h,"left",n-i/2+"px")}(a):f(a),0===n?V(o,"art-progress-hover"):W(o,"art-progress-hover")),"played"===r&&(j(d,"width",100*n+"%"),j(p,"left",100*n+"%")),m){W(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Wt(i,()=>{V(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 Ht(t){return e=>c(l({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{jt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=M(t,e);if(!I){let e=!1;i(r,"click",e=>{e.target!==n&&Bt(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=Yt(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=Yt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function qt(t){const{option:e}=t.art;e.isLive||t.add(Ht({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.play),s=Tt(t,o.pause);function l(){j(a,"display","flex"),j(s,"display","none")}function c(){j(a,"display","none"),j(s,"display","flex")}X(a,i.get("Play")),X(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=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=M(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}=tt(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)j(i,"display","none"),j(a,"display","flex"),j(h,"top","100%"),j(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;j(i,"display","flex"),j(a,"display","none"),j(h,"top",100-t+"%"),j(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}),I)j(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=>c(l({},t),{style:I?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=M(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&&!$(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!I&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=M(e,t),{icons:n}=e;Tt(t,n.screenshot),r(t,"click",()=>{e.screenshot()})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e;Tt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{X(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e;Tt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{X(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=>c(l({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=M(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=>c(l({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenWebOn),s=Tt(t,o.fullscreenWebOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(X(t,i.get("Exit Web Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(X(t,i.get("Web Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenOn),s=Tt(t,o.fullscreenOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(X(t,i.get("Exit Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(X(t,i.get("Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rXt.get(t).option.selector}),gt(t,"$control_item",{get:()=>Xt.get(t).item}),gt(t,"$control_value",{get:()=>Xt.get(t).value})),Xt.set(t,e)}function Kt(t,e){t.innerHTML=e}function Zt(t,e,r,n,o){const{proxy:i}=t.events,a=S(n),s=r.selector;W(n,"art-control-selector");const l=document.createElement("div");W(l,"art-selector-value"),B(l,r.html),n.textContent="",B(n,l);const c=Tt(n,'
');for(let d=0;dd(null,null,function*(){if(a.closed)return;const o=rt(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 Ut.set(t,e),()=>{Ut.get(t)===e&&Ut.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()&&Kt(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class Jt extends Nt{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;L(t,n);const{on:o}=M(t,n);o("mousemove",()=>{I||(this.show=!0)}),o("click",()=>{I?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=G(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?(V(r,"art-hide-cursor"),W(r,"art-hover"),this.timer=Date.now()):(W(r,"art-hide-cursor"),V(r,"art-hover"))}),this.init(),$(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=S(e),{on:i}=M(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(){qt(this)}add(t){if(E(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){Kt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Qt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(E(t))return;const o=G(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),$(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(E(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),E(t))return;(!I||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),E(t))return;I?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}const te=new WeakMap,ee=new WeakMap,re=new WeakMap;function ne(t){return re.get(t)||$(t)}function oe(t){const e=te.get(t),r=re.get(t);return()=>te.get(t)===e&&(!e||e.active())&&re.get(t)===r&&(!r||!r.closed)}function ie(t){const e=re.get(t),r=$(t).child(),n=r.child();re.set(t,r),r.add(()=>{re.get(t)===r&&re.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!E(t)&&!n.closed&&te.get(t)===o};return te.set(t,o),n.add(()=>{te.get(t)===o&&te.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function ae(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function se(t,e,r){ee.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{ee.get(t)===e&&(ee.delete(t),ae(e))}}function le(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function ce(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!E(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),$(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(E(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:oe(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{Bt(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(E(t))return;const n=(...e)=>{if(!E(t))return r(...e)};t.on(e,n),$(t).add(()=>{t.off(e,n)})}}function ge(t){if(!t.constructor.USE_RAF)return;const e=$(t);let r=()=>{};const n=()=>{E(t)||(t.playing&&t.emit("raf"),E(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:$(e),cleaning:!1})}(this,t),$(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Qt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{E(t)||(W(r,"art-hover"),t.emit("hover",!0,e))},e=>{E(t)||(V(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{E(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(),E(t)||(t.aspectRatio=e,E(t)||(r.show=""))});const s=$(t);let l=()=>{};const c=()=>{E(t)||(l(),l=Wt(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(!I||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=$(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)),E(t)||(s=!0,Wt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;$(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(E(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||E(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||E(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}),I||this.init()}init(){const t=this.art;if(E(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(!E(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=l(l({},Ee),t.option.icons);for(const r in e)gt(this,r,{get:()=>J(r,e[r])})}}class Ce extends Nt{constructor(t){super(t),this.name="info",I||this.init()}init(){const{proxy:t,constructor:e,template:{$infoPanel:r,$infoClose:n,$video:o}}=this.art;t(n,"click",()=>{this.show=!1});let i=()=>{};const a=F("[data-video]",r)||[];this.art.on("destroy",()=>i());const s=$(this.art);!function t(){for(let e=0;e{j(o,"display","none"),j(i,"display",null)}),n.proxy(e.$state,"click",()=>at(t.play()))}}class Me{constructor(t){this.art=t,this.timer=null,$(t).add(()=>this.destroy()),t.on("destroy",()=>this.destroy())}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}set show(t){if($(this.art).closed)return;const{constructor:e,template:{$player:r,$noticeInner:n}}=this.art;t?(n.textContent=t instanceof Error?t.message.trim():t,W(r,"art-notice-show"),clearTimeout(this.timer),this.timer=setTimeout(()=>{n.textContent="",V(r,"art-notice-show")},e.NOTICE_TIME)):V(r,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function ze({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ae(t,e){if(!ze(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 ze(r)?r:void 0}function Oe(t){const{$container:e,$video:r}=t.template;gt(t,"autoHeight",{value(){if(E(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!ze(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||E(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function Re(t,e,r,n=!1){const o=e=>{E(t)||r(e)};t[n?"once":"on"](e,o),$(t).add(()=>{t.off(e,o)})}function Ie(t,e,r){for(const[n,o]of e){if(E(t)||r&&!r())return;t[n].show=o}}function _e(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=ne(t),l=0;return{reset(){l=0,null==a||a.dispose(),V(i,"art-error")},loadStart(){V(i,"art-error")},schedule(c){(c=>d(null,null,function*(){if(E(t))return;const d=ne(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!E(t)&&!u.closed&&d===ne(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Ne(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{E(t)||t.emit(`video:${e.type}`,e)})}(t);const e=_e(t);!function(t,e){Re(t,"video:canplay",()=>{e.reset(),Ie(t,[["loading",!1]])}),Re(t,"video:canplay",()=>{Ie(t,[["loading",!1],["controls",!0],["mask",!0]]),E(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Re(t,"video:ended",()=>{if(e.loop){const e=oe(t);if(t.seek=0,E(t)||!e())return;at(t.play()),e()&&Ie(t,[["controls",!1],["mask",!1]],e)}else Ie(t,[["controls",!0],["mask",!0]])})}(t),Re(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Re(t,"video:loadedmetadata",()=>{t.emit("resize"),I&&Ie(t,[["loading",!1],["controls",!0],["mask",!0]])}),Re(t,"video:loadstart",()=>{e.loadStart(),Ie(t,[["loading",!0],["mask",!1],["controls",!0]])}),Re(t,"video:pause",()=>{Ie(t,[["controls",!0],["mask",!0]])}),Re(t,"video:play",()=>{Ie(t,[["mask",!1]]),E(t)||j(r,"display","none")}),Re(t,"video:playing",()=>Ie(t,[["mask",!1]])),Re(t,"video:progress",()=>{t.playing&&Ie(t,[["loading",!1]])}),Re(t,"video:seeked",()=>Ie(t,[["loading",!1],["mask",!0]])),Re(t,"video:seeking",()=>Ie(t,[["loading",!0],["mask",!1]])),Re(t,"video:timeupdate",()=>Ie(t,[["mask",!1]])),Re(t,"video:waiting",()=>Ie(t,[["loading",!0],["mask",!1]]))}(t,e)}const De=[["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"]],Fe=(()=>{if("undefined"===typeof document)return!1;const t=De[0],e={};for(const r of De){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),We={change:Fe.fullscreenchange,error:Fe.fullscreenerror},Ve={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Ve.off("change",o),r()};Ve.on("change",o);const i=t[Fe.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Ve.isFullscreen)return void t();const r=()=>{Ve.off("change",r),t()};Ve.on("change",r);const n=document[Fe.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Ve.isFullscreen?Ve.exit():Ve.request(t,e),onchange(t){Ve.on("change",t)},onerror(t){Ve.on("error",t)},on(t,e){const r=We[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=We[t];r&&document.removeEventListener(r,e,!1)},raw:Fe};function Ye(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(Ve,{isFullscreen:{get:()=>Boolean(document[Fe.fullscreenElement])},element:{enumerable:!0,get:()=>document[Fe.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Fe.fullscreenEnabled])}});const Be=new WeakMap;function je(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function He(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Be.get(t);if(!n){n=new WeakMap,Be.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),je(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),je(i))}function qe(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&&He(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Ft(i,t.document,t.changeEvent,m),Ft(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=Be.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&&He(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 Ue(t,e){const r=$(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()}),Ft(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=Be.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||E(t))return;s=r;const o=l,a=()=>E(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")))}),Ft(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!E(t)&&t.emit("fullscreenError",r)}),{get:()=>!E(t)&&i(),set(n){if(E(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=qe(e,r,c,()=>{!E(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw E(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const Xe=new WeakSet;function Ge(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Ke(t){Xe.delete(t),t.removeEventListener("webkitbeginfullscreen",Ze),t.removeEventListener("webkitpresentationmodechanged",Ze)}function Ze(t){var e;if(Xe.has(this)&&Ge(this,"webkitbeginfullscreen"===t.type)){Ke(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function Je(t){Xe.add(t),t.addEventListener("webkitbeginfullscreen",Ze),t.addEventListener("webkitpresentationmodechanged",Ze)}function Qe(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=Ge(e),i=o,a=!1,s=0;const l=()=>Ge(e,n);function c(r){if(E(t)||(c=e,Xe.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=()=>E(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&&Je(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Ft(r,e,"webkitbeginfullscreen",()=>c(!0)),Ft(r,e,"webkitendfullscreen",()=>c(!1)),Ft(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!E(t)&&l(),set(r){if(E(t))return;const n=++s;if(i=Boolean(r),r){if(Ke(e),t.state="fullscreen",E(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 tr(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(E(t))return;const i=function(t){const e=Ve.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:()=>Ye(t,e.requestFullscreen,void 0),exit:()=>Ye(r,e.exitFullscreen)}}(o);i?gt(t,"fullscreen",Ue(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?gt(t,"fullscreen",Qe(t)):gt(t,"fullscreen",{get:()=>!1,set(){E(t)||(r.show=e.get("Fullscreen Not Supported"))}}),gt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),$(t).add(()=>{t.off("video:loadedmetadata",i)})}function er(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function rr({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 nr(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()&&(rr(t.placement),r()))}return $(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 y([a,s])}throw a}}),i=>{if(E(t))return;const a=++n,s=()=>a===n&&!E(t);if(i){r||(r={placement:er(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 or(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 ir(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function ar(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),Ft(o,e,"click",n),Ft(o,l,"click",()=>{at(t.play())}),Ft(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=""};Ft(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=or(i.left,i.top,ir(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 sr(t){const{$player:e,$video:r}=t.template,n=$(t).child();let o,i,a=0,s=!1,d=!1;const u=()=>!E(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{rr(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(E(t))return;const r=++a;d=!1,p(),E(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(E(t))return;const m=++a;if(s)d=!0;else if(t.state="mini",!E(t)&&m===a){null!=i||(i=er(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=ar(t,n,u,h)}finally{s=!1}}if(d)return d=!1,void f();if(!o||E(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),E(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}:c(l({},or(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,ir(o.element));if(E(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),E(t)||m!==a)return;t.storage.set("left",i.left)}E(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,E(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 lr=new WeakSet,cr=t=>"picture-in-picture"===t.webkitPresentationMode;function dr(t){lr.delete(t),t.removeEventListener("webkitpresentationmodechanged",ur),t.removeEventListener("enterpictureinpicture",ur)}function ur(){var t;if(lr.has(this)&&cr(this)){dr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function pr(t){lr.add(t),t.addEventListener("webkitpresentationmodechanged",ur),t.addEventListener("enterpictureinpicture",ur)}function hr(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=$(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||!E(t)&&a||d()},e=>{E(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Ft(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!E(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Ft(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!E(t)&&o()?e:null,set(n){if(E(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",E(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=$(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(E(t)||lr.has(e))return;const s=cr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),E(t)||i!==l||cr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&pr(e),cr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Ft(r,e,l,()=>s());return{get:()=>!E(t)&&cr(e),set(r){var n;if(E(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(dr(e),t.state="pip",E(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,pr(e)),cr(e)&&e.webkitSetPresentationMode("inline");E(t)||l!==i||c!==a||cr(e)!==Boolean(r)||s(!0)}}}(t)):gt(t,"pip",{get:()=>!1,set(){E(t)||(r.show=e.get("PIP Not Supported"))}})}function fr(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 d(this,null,function*(){const r=function(t){return t&&Ut.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!E(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!E(t)&&r()&&(n.show=i)}return e.html})}})}})}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(E(t)||e===t.url)return void n();const i=ie(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(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child(),h={"video:error":u,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){u(e)}},"video:canplay":()=>{if(!c())return;p.dispose();d(null,null,function*(){if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{yield t.play()}catch(e){}c()&&(t.notice.show="",l())}}).catch(u)}},f=a.child(),m=[],g=Object.keys(h);for(const e of g)mr(f,t,e,t=>{i.acceptingEvents&&m.push([e,t])},!1);if(se(t,i,e),!c())return;if(t.notice.show="",!c())return;const v=()=>{if(f.dispose(),!e)return void l();const r={};for(const e of g)r[e]=mr(p,t,e,h[e]);for(const[t,e]of m){if(!c()||p.closed)break;r[t](e)}m.length=0};i.assigned?v():i.onAssigned=v}catch(p){u(p)}})}function vr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",(o,s,l)=>d(null,null,function*(){var c;const d=null==(c=t.controls)?void 0:c.thumbnails,{url:u,scale:p}=e.thumbnails;if(!d||!u)return;if("hover"===o||"played"===o&&l&&I){if(a||i||(i=!0,a=yield et(u,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-h/2?j(s,"left",r.clientWidth-h+"px"):j(s,"left",o-h/2+"px")}(o)}})),gt(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function yr(t){const{option:e,template:{$video:r}}=t;gt(t,"url",{get:()=>r.src,set(n){return d(this,null,function*(){if(E(t))return;const o=function(t){const e=ee.get(t);return ee.delete(t),e||ie(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=>le(o,t))}else{if(i&&URL.revokeObjectURL(i),!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){le(o,i)}finally{ae(o)}})}})}class br{constructor(t){yr(t),function(t){const{template:{$video:e}}=t;gt(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;gt(t,"play",{value(){return d(this,null,function*(){const a=oe(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()})}(t),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}})}(t),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)}})}(t),function(t){const{$video:e}=t.template;gt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=ct(n,0,t.duration))}})}(t),function(t){gt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),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})}(t),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}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;gt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!E(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=Ae({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(E(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}`,E(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=Z("canvas");gt(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),gt(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),gt(t,"screenshot",{value:e=>d(null,null,function*(){const n=yield t.getDataURL();return lt(n,`${e||`artplayer_${ut(r.currentTime)}`}.png`),t.emit("screenshot",n),n})})}(t),tr(t),nr(t),hr(t),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})}(t),function(t){gt(t,"played",{get:()=>t.currentTime/t.duration})}(t),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)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;gt(t,"autoSize",{value(){if(E(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!ze(o))return;const i=tt(e),a=Ae(i,o.width/o.height);a&&!E(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}))}})}(t),function(t){const e=t;gt(t,"rect",{get:()=>tt(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})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;gt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){E(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,E(t)||t.emit("flip",o))}})}(t),function(t){gt(t,"mini",sr(t))}(t),function(t){const{template:{$poster:e}}=t;gt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){j(e,"backgroundImage",`url(${t})`)}})}(t),Oe(t),function(t){const{$player:e}=t.template;gt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){gt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){gt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),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{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,gt(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),fr(t),vr(t),Ne(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=ct(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=ct(i,0,1)),e.poster&&j(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(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 ze(t)&&ze(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=$(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,E(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=nt();if(E(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;E(t)||(r?o?s(!1):e()&&(i(),i=Wt(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 $(t).add(o),i=>{var a,s;if(E(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=()=>!E(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),$(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Cr(t){const{i18n:e,icons:r,storage:n,constructor:o,proxy:i,template:{$poster:a}}=t,s=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '}),l=D(".art-auto-playback-last",s),c=D(".art-auto-playback-jump",s),d=D(".art-auto-playback-close",s);B(d,r.close);let u=null;function p(){const r=(n.get("times")||{})[t.option.id||t.option.url];clearTimeout(u),j(s,"display","none"),r&&r>=o.AUTO_PLAYBACK_MIN&&(j(s,"display","flex"),l.textContent=`${e.get("Last Seen")} ${ut(r)}`,c.textContent=e.get("Jump Play"),i(d,"click",()=>{j(s,"display","none")}),i(c,"click",()=>{t.seek=r,at(t.play()),j(a,"display","none"),j(s,"display","none")}),t.once("video:timeupdate",()=>{u=setTimeout(()=>{j(s,"display","none")},o.AUTO_PLAYBACK_TIMEOUT)}))}return t.on("video:timeupdate",()=>{if(t.playing){const e=n.get("times")||{},r=Object.keys(e);r.length>o.AUTO_PLAYBACK_MAX&&delete e[r[0]],e[t.option.id||t.option.url]=t.currentTime,n.set("times",e)}}),t.on("ready",p),t.on("restart",p),{name:"auto-playback",get times(){return n.get("times")||{}},clear:()=>n.del("times"),delete(t){const e=n.get("times")||{};return delete e[t],n.set("times",e),e}}}function Lr(t){const{constructor:e,proxy:r,template:{$player:n,$video:o}}=t;let i=null,a=!1,s=1;const l=()=>{clearTimeout(i),a&&(a=!1,t.playbackRate=s,V(n,"art-fast-forward"))};return r(o,"touchstart",r=>{1===r.touches.length&&t.playing&&!t.isLock&&(i=setTimeout(()=>{a=!0,s=t.playbackRate,t.playbackRate=e.FAST_FORWARD_VALUE,W(n,"art-fast-forward")},e.FAST_FORWARD_TIME))}),t.on("document:touchmove",l),t.on("document:touchend",l),{name:"fastForward",get state(){return Y(n,"art-fast-forward")}}}function Sr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return Y(n,"art-lock")}function i(){W(n,"art-lock"),t.isLock=!0,t.emit("lock",!0)}function a(){V(n,"art-lock"),t.isLock=!1,t.emit("lock",!1)}return e.add({name:"lock",mounted(e){const n=B(e,r.lock),o=B(e,r.unlock);j(n,"display","none"),t.on("lock",t=>{t?(j(n,"display","inline-flex"),j(o,"display","none")):(j(n,"display","none"),j(o,"display","inline-flex"))})},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function Pr(t){return t.on("control",e=>{e?V(t.template.$player,"art-mini-progress-bar"):W(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Mr{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){E(t.art)||!e.miniProgressBar||e.isLive||t.add(Pr),!E(t.art)&&e.lock&&I&&t.add(Sr),E(t.art)||!e.autoPlayback||e.isLive||t.add(Cr),!E(t.art)&&e.autoOrientation&&I&&t.add(Tr),!E(t.art)&&e.fastForward&&I&&!e.isLive&&t.add(Lr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!E(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(E(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(E(t.art))return t;let o=n;const i=yt(t,o);if(E(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return E(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),E(t.art)||gt(t,o,{value:r})),t}(this,t,e)}}const zr=new WeakMap;function Ar(t){return!t.closed&&!zr.get(t)}function Or(t){zr.set(t,(zr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(zr.get(t)||1)-1;r?zr.set(t,r):zr.delete(t)}}const Rr=new WeakMap,Ir=new WeakMap,_r=["$parent","$parents","$option","$events","$formatted"];function Nr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Rr.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=Rr.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function Dr(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 Fr(t){const e=Rr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Wr(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>Ur(t,o)])try{e()}catch(d){d instanceof y?l.push(...d.errors):l.push(d)}if(r.closed||E(t)||(o.push(...i.splice(0)),qr.set(r,o),jr.set(e,r),Hr.set(e,n)),a(),l.length)throw new y(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function Jr(t,e,r,n,o,i){const a=i||Gr(e);if(!Ar(a)||E(t))return;const s=t.proxy(r,n,e=>{if(Ar(a)&&!E(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Ar(a)||E(t)?t.events.remove(s):(Fr(e).events.push(s),i&&i!==jr.get(e)&&i.add(()=>{const r=Fr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Qr(t,e,r,n){const o=Gr(e);if(!Ar(o)||E(t))return;const i=(...e)=>{if(Ar(o)&&!E(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function tn(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||I||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const en=new WeakMap;function rn(t){en.delete(t)}const nn=new WeakMap;function on(t,e){e?nn.set(t,e):nn.delete(t)}function an(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=nn.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(),on(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 sn=new WeakMap;function ln(t,e,r,n,o,i,a,s){return d(this,null,function*(){try{const l=Gr(e),c=Gr(i),d=(sn.get(i)||0)+1;sn.set(i,d);const u=()=>Ar(l)&&Ar(c)&&!E(t.art)&&sn.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 cn(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 dn=new WeakMap;function un(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof y?e.push(...r.errors):e.push(r)}if(e.length)throw new y(e)}function pn(t){var e;null==(e=dn.get(t))||e()}function hn(t,e){const r=t.find(e.name);if(E(t.art))return r||e;if(!r)return t.add(e);rn(r),pn(r);const n=an(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?cn(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=Zr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Or(Yr(t)))}catch(l){try{un([...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,un([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,un([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Br(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)dn.get(t)===h&&dn.delete(t);if(E(t.art))return void d.dispose();const e=r.$item;try{un([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)&&U(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&&!E(t.art)&&dn.get(r)===h;for(const v of d.items)dn.set(v,h);const m=$(t.art).add(()=>{u=!1;for(const t of d.items)dn.get(t)===h&&dn.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)dn.get(t)===h&&dn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const fn=new WeakMap;function mn(t,e,r){gt(t,`$${e}`,{configurable:!0,get:()=>r}),gt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",B(r,t)}})}function gn(t,e,r=!1){var n,o;const i=function(t){const e=dn.get(t);return()=>!e||dn.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=$(t)){const n=jr.get(e);(!n||Ar(n)||n.closed)&&Kr(t,e);const o=r.child();return jr.set(e,o),Hr.set(e,r),qr.set(o,Fr(e).events),o.add(()=>{Ur(t,qr.get(o))}),o}(t.art,e,Yr(a)),p=()=>Ar(u)&&!E(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(on(e),W(h,"art-setting-item"),j(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=B(h,'
'),f=B(h,'
'),m=document.createElement("div");switch(W(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;B(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;B(m,t)}else B(m,c.check)}if(B(i,m),!p())return;mn(e,"icon",m);const g=document.createElement("div");W(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;B(g,v),B(i,g),mn(e,"html",g);const y=document.createElement("div");W(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(B(y,b),B(f,y),mn(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");W(t,"art-setting-item-right-icon");const r=B(t,c.switchOn),n=B(t,c.switchOff),o=e.switch;if(!p())return;j(o?n:r,"display","none"),B(f,t),gt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;on(e,()=>{const t=i;return()=>{i=t}}),gt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(j(n,"display","none"),j(r,"display",null)):(j(n,"display",null),j(r,"display","none"))}});break}case"range":{const t=document.createElement("div");W(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",B(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))}W(r,"art-setting-range"),B(f,t),gt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;on(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");W(t,"art-setting-item-right-icon"),B(t,c.arrowRight),B(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=Gr(e),a=(t,r,n)=>Jr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>ln(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=>ln(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 ln(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&W(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>ln(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):B(a,h),e.mounted&&p()&&Wt(u,()=>{var r;if(!E(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 vn(t,e=t.option){var r;if(E(t.art))return;const n=t.cache.get(e);if(n&&!Ar(Yr(n)))return;const o=(fn.get(t)||0)+1;fn.set(t,o);const i=()=>fn.get(t)===o&&!E(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)&&U(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{U(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Yr(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=$(t.art).child();return Vr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!E(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;W(n,"art-setting-panel"),B(t.$parent,n),U(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Ir.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=$(e).child(),n=(t,n)=>{if(r.closed||E(e))return;const o=(...t)=>{if(!r.closed&&!E(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=G(r,e.controls.setting),o=G(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||E(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(),Qr(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(),Qr(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(),Qr(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)=>{Qr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Wr(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&&U(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=Ir.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;oFr(t).parent},$parents:{get:()=>Fr(t).parents},$option:{get:()=>Fr(t).option},$events:{get:()=>Fr(t).events},$formatted:{get:()=>!0}}),Rr.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 Wr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){tn(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&&Br(n)}catch(i){r.push(i)}}try{Kr(t.art,e)}catch(i){i instanceof y?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new y(r)}(this,t)}remove(t){const e=this.find(t);it(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{rn(t),pn(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 y?o.push(...i.errors):o.push(i)}if(o.length)throw new y(o)}update(t){return hn(this,t)}add(t,e=this.option){var r;if(E(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={};en.set(t,e);const r=()=>en.get(t)===e;return{current:r,finish(){r()&&en.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(E(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");j(i,"height",`${o}px`),W(i,"art-setting-item"),W(i,"art-setting-item-back");const a=B(i,'
'),s=document.createElement("div");W(s,"art-setting-item-left-icon"),B(s,n),B(a,s),B(a,e.$parent.html),Jr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Yr(r)),B(r,i)}(this,t)}createItem(t,e=!1){gn(this,t,e)}render(t=this.option){vn(this,t)}}class wn{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 xn='.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 kn{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 d(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const $n=new WeakMap;function En(t){return $n.get(t)}function Tn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const Cn=Nt;class Ln extends Cn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=$(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return $n.set(t,n),r.add(()=>{Tn(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?H(r,t):j(r,t,e)}update(){!function(t){const e=En(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 d(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=c(l(l({},o.subtitle),e),{url:t}),a=En(this),s=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=En(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&&Tn(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 d(this,null,function*(){const e=En(this),r=function(t){const e=t.request,r=new kn(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(()=>d(this,null,function*(){if(!this.textTrack)return null;if(m(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 Sn=`\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
${g}
\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 Pn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=D(e.container),it(this.$container,`No container element found by ${e.container}`)),it(Q(),"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=x.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=k(t);o.rollback=r,x.set(e,t),o.releaseContainer=()=>{x.get(e)===t&&x.delete(e)}}(t,this.$container,cn(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return Sn}query(t){return D(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Pn.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);!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),K(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&W(this.$player,"art-backdrop"),I&&W(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":W(this.$player,"art-destroy")}}const Mn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class zn{on(t,e,r){const n=this.e||(this.e={});let o=Mn(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=(Mn(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=Mn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;ie.call(this,this)),Rn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Rn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=k(t);return e.rollback=void 0,!e.scope.closed})(this)&&On.push(this)}catch(n){try{T(this,On,!0,Rn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(o){console.warn("Failed to clean up ArtPlayer initialization:",o)}throw n}}static get instances(){return On}static get version(){return g}static get config(){return v}static get utils(){return Et}static get scheme(){return It}static get Emitter(){return zn}static get validator(){return m}static get kindOf(){return m.kindOf}static get html(){return Pn.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:A?"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){T(this,On,t,Rn.REMOVE_SRC_WHEN_DESTROY)}}return Rn.STYLE=xn,Rn.DEBUG=!1,Rn.CONTEXTMENU=!0,Rn.NOTICE_TIME=2e3,Rn.SETTING_WIDTH=250,Rn.SETTING_ITEM_WIDTH=200,Rn.SETTING_ITEM_HEIGHT=35,Rn.RESIZE_TIME=200,Rn.SCROLL_TIME=200,Rn.SCROLL_GAP=50,Rn.AUTO_PLAYBACK_MAX=10,Rn.AUTO_PLAYBACK_MIN=5,Rn.AUTO_PLAYBACK_TIMEOUT=3e3,Rn.RECONNECT_TIME_MAX=5,Rn.RECONNECT_SLEEP_TIME=1e3,Rn.CONTROL_HIDE_TIME=3e3,Rn.DBCLICK_TIME=300,Rn.DBCLICK_FULLSCREEN=!0,Rn.MOBILE_DBCLICK_PLAY=!0,Rn.MOBILE_CLICK_PLAY=!1,Rn.AUTO_ORIENTATION_TIME=200,Rn.INFO_LOOP_TIME=1e3,Rn.FAST_FORWARD_VALUE=3,Rn.FAST_FORWARD_TIME=1e3,Rn.TOUCH_MOVE_RATIO=.5,Rn.VOLUME_STEP=.1,Rn.SEEK_STEP=5,Rn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Rn.ASPECT_RATIO=["default","4:3","16:9"],Rn.FLIP=["normal","horizontal","vertical"],Rn.FULLSCREEN_WEB_IN_BODY=!0,Rn.LOG_VERSION=!0,Rn.USE_RAF=!1,Rn.REMOVE_SRC_WHEN_DESTROY=!0,_&&(window.Artplayer=Rn,N("artplayer-style",xn),setTimeout(()=>{Rn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Rn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Rn}); diff --git a/docs/compiled/artplayer.mjs b/docs/compiled/artplayer.mjs index cf92ebd7c..d64a25074 100644 --- a/docs/compiled/artplayer.mjs +++ b/docs/compiled/artplayer.mjs @@ -361,29 +361,29 @@ class ResourceScope { throw new ResourceCleanupError(errors); } } -const states$2 = /* @__PURE__ */ new WeakMap(); +const states$4 = /* @__PURE__ */ new WeakMap(); const containers = /* @__PURE__ */ new WeakMap(); function beginLifecycle(owner) { - states$2.set(owner, { scope: new ResourceScope(), destroying: false }); + states$4.set(owner, { scope: new ResourceScope(), destroying: false }); } -function stateOf(owner) { - const state2 = states$2.get(owner); +function stateOf$1(owner) { + const state2 = states$4.get(owner); if (!state2) throw new Error("ArtPlayer lifecycle has not been initialized"); return state2; } function getScope(owner) { - return stateOf(owner).scope; + return stateOf$1(owner).scope; } function isClosing(owner) { - const state2 = stateOf(owner); + const state2 = stateOf$1(owner); return state2.destroying || state2.scope.closed; } function ownContainer(owner, container, rollback) { const current2 = containers.get(container); if (current2 && current2 !== owner) throw new Error("Cannot mount multiple instances on the same dom element"); - const state2 = stateOf(owner); + const state2 = stateOf$1(owner); state2.rollback = rollback; containers.set(container, owner); state2.releaseContainer = () => { @@ -392,12 +392,12 @@ function ownContainer(owner, container, rollback) { }; } function finishLifecycle(owner) { - const state2 = stateOf(owner); + const state2 = stateOf$1(owner); state2.rollback = void 0; return !state2.scope.closed; } function destroyInstance(owner, instances2, removeHtml, removeSource, failed = false) { - const state2 = stateOf(owner); + const state2 = stateOf$1(owner); if (state2.destroying || state2.scope.closed) return; state2.destroying = true; @@ -432,20 +432,20 @@ function destroyInstance(owner, instances2, removeHtml, removeSource, failed = f if (errors.length) throw errors[0]; } -const scopes$3 = /* @__PURE__ */ new WeakMap(); +const scopes$2 = /* @__PURE__ */ new WeakMap(); function ownEntry(art, element) { const scope = getScope(art).child(); - scopes$3.set(element, scope); + scopes$2.set(element, scope); return scope; } function entryScope(element) { - const scope = scopes$3.get(element); + const scope = scopes$2.get(element); if (!scope) throw new Error("ArtPlayer component has not been registered"); return scope; } function releaseEntry(element) { - scopes$3.get(element)?.dispose(); + scopes$2.get(element)?.dispose(); } function proxyEntry(art, element, target, name, callback) { const scope = entryScope(element); @@ -1620,16 +1620,18 @@ function getPosFromEvent(art, event) { const percentage = clamp(width / $progress.clientWidth, 0, 1); return { second, time: time2, width, percentage }; } -function setCurrentTime(art, event) { +function setCurrentTime(art, event, active2 = () => true) { if (art.isRotate) { const percentage = (event.touches[0].clientY - art.top) / art.height; const second = percentage * art.duration; art.emit("setBar", "played", percentage, event); - art.seek = second; + if (active2()) + art.seek = second; } else { const { second, percentage } = getPosFromEvent(art, event); art.emit("setBar", "played", percentage, event); - art.seek = second; + if (active2()) + art.seek = second; } } function installProgressInteractions(art, $control) { @@ -2213,26 +2215,30 @@ class Control extends Component { renderSelector(this.art, (target) => this.check(target), option, $ref, events); } } -function clickInit(art, events) { - const { - constructor, - template: { $player, $video } - } = art; - function onDocumentClick(event) { - if (includeFromEvent(event, $player)) { - art.isInput = event.target.tagName === "INPUT"; - art.isFocus = true; - art.emit("focus", event); - } else { - art.isInput = false; - art.isFocus = false; - art.emit("blur", event); - } - } +function pointerFocus(art) { + const { $player } = art.template; + const onDocumentClick = (event) => { + if (isClosing(art)) + return; + const inside = includeFromEvent(event, $player); + art.isInput = inside && event.target?.tagName === "INPUT"; + art.isFocus = inside; + art.emit(inside ? "focus" : "blur", event); + }; art.on("document:click", onDocumentClick); art.on("document:contextmenu", onDocumentClick); + getScope(art).add(() => { + art.off("document:click", onDocumentClick); + art.off("document:contextmenu", onDocumentClick); + }); +} +function clickInit(art, events) { + const { constructor, template: { $video } } = art; + pointerFocus(art); let clickTimes = []; events.proxy($video, "click", (event) => { + if (isClosing(art)) + return; const now = Date.now(); clickTimes.push(now); const { MOBILE_CLICK_PLAY, DBCLICK_TIME, MOBILE_DBCLICK_PLAY, DBCLICK_FULLSCREEN } = constructor; @@ -2240,25 +2246,21 @@ function clickInit(art, events) { switch (clicks.length) { case 1: art.emit("click", event); - if (isMobile) { - if (!art.isLock && MOBILE_CLICK_PLAY) { - silencePromise(art.toggle()); - } - } else { + if (isClosing(art)) + return; + if (!isMobile || !art.isLock && MOBILE_CLICK_PLAY) silencePromise(art.toggle()); - } clickTimes = clicks; break; case 2: art.emit("dblclick", event); + if (isClosing(art)) + return; if (isMobile) { - if (!art.isLock && MOBILE_DBCLICK_PLAY) { + if (!art.isLock && MOBILE_DBCLICK_PLAY) silencePromise(art.toggle()); - } - } else { - if (DBCLICK_FULLSCREEN) { - art.fullscreen = !art.fullscreen; - } + } else if (DBCLICK_FULLSCREEN) { + art.fullscreen = !art.fullscreen; } clickTimes = []; break; @@ -2267,131 +2269,251 @@ function clickInit(art, events) { } }); } -function GetSlideAngle(dx, dy) { - return Math.atan2(dy, dx) * 180 / Math.PI; +const current = /* @__PURE__ */ new WeakMap(); +const assignments = /* @__PURE__ */ new WeakMap(); +const sources = /* @__PURE__ */ new WeakMap(); +function getSourceScope(owner) { + return sources.get(owner) || getScope(owner); } -function GetSlideDirection(startX, startY, endX, endY) { +function captureSource(owner) { + const operation = current.get(owner); + const source = sources.get(owner); + return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed); +} +function beginSource(owner) { + const previous = sources.get(owner); + const source = getScope(owner).child(); + const scope = source.child(); + sources.set(owner, source); + source.add(() => { + if (sources.get(owner) === source) + sources.delete(owner); + }); + const operation = { + scope, + assigned: false, + acceptingEvents: false, + active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation + }; + current.set(owner, operation); + scope.add(() => { + if (current.get(owner) === operation) + current.delete(owner); + operation.onAssigned = void 0; + operation.onError = void 0; + }); + previous?.dispose(); + return operation; +} +function takeAssignment(owner) { + const operation = assignments.get(owner); + assignments.delete(owner); + return operation || beginSource(owner); +} +function finishAssignment(operation) { + operation.assigned = true; + const callback = operation.onAssigned; + operation.onAssigned = void 0; + if (operation.active()) + callback?.(); +} +function assignUrl(owner, operation, url) { + assignments.set(owner, operation); + operation.acceptingEvents = true; + try { + owner.url = url; + } finally { + if (assignments.get(owner) === operation) { + assignments.delete(owner); + finishAssignment(operation); + } + } +} +function failSource(operation, error2) { + if (!operation.active()) + return; + if (operation.onError) + operation.onError(error2); + else + console.warn("Failed to initialize ArtPlayer source:", error2); + operation.scope.dispose(); +} +function slideDirection(startX, startY, endX, endY) { const dy = startY - endY; const dx = endX - startX; - let result = 0; - if (Math.abs(dx) < 2 && Math.abs(dy) < 2) { - return result; - } - const angle = GetSlideAngle(dx, dy); - if (angle >= -45 && angle < 45) { - result = 4; - } else if (angle >= 45 && angle < 135) { - result = 1; - } else if (angle >= -135 && angle < -45) { - result = 2; - } else if (angle >= 135 && angle <= 180 || angle >= -180 && angle < -135) { - result = 3; - } - return result; + if (Math.abs(dx) < 2 && Math.abs(dy) < 2) + return 0; + const angle = Math.atan2(dy, dx) * 180 / Math.PI; + if (angle >= -45 && angle < 45) + return 4; + if (angle >= 45 && angle < 135) + return 1; + if (angle >= -135 && angle < -45) + return 2; + if (angle >= 135 && angle <= 180 || angle >= -180 && angle < -135) + return 3; + return 0; +} +function gestureController(art) { + let drag; + const cancel = () => { + drag = void 0; + }; + const active2 = (current2) => drag === current2 && !isClosing(art) && !art.isLock && !art.option.isLive && art.isRotate === current2.rotated && current2.sourceActive(); + const onLock = (locked) => { + if (locked) + cancel(); + }; + art.on("document:touchend", cancel); + art.on("document:touchcancel", cancel); + art.on("lock", onLock); + getScope(art).add(() => { + cancel(); + art.off("document:touchend", cancel); + art.off("document:touchcancel", cancel); + art.off("lock", onLock); + }); + const start = (target, event) => { + cancel(); + const touch = event.touches[0]; + if (isClosing(art) || art.isLock || art.option.isLive || event.touches.length !== 1 || !touch) + return; + if (![touch.pageX, touch.pageY, touch.clientX, touch.clientY, art.currentTime].every(Number.isFinite)) + return; + const current2 = { + target, + identifier: touch.identifier, + x: touch.pageX, + y: touch.pageY, + time: art.currentTime, + rotated: art.isRotate, + sourceActive: captureSource(art) + }; + drag = current2; + if (target === art.template.$progress) { + const size = art.isRotate ? art.height : art.template.$progress.clientWidth; + if (!Number.isFinite(size) || size <= 0 || !Number.isFinite(art.duration) || art.duration <= 0) { + cancel(); + return; + } + try { + setCurrentTime(art, event, () => active2(current2)); + } catch (error2) { + if (drag === current2) + cancel(); + throw error2; + } + if (active2(current2)) + current2.time = art.currentTime; + } + }; + const move = (event) => { + const current2 = drag; + const touch = event.touches[0]; + if (!current2) + return; + if (!active2(current2) || event.touches.length !== 1 || !touch || touch.identifier !== current2.identifier) { + cancel(); + return; + } + const size = current2.rotated ? art.height : art.width; + const multiplier = current2.target === art.template.$video ? art.constructor.TOUCH_MOVE_RATIO : 1; + if (![touch.pageX, touch.pageY, size, art.duration, multiplier].every(Number.isFinite) || size <= 0 || art.duration <= 0) { + cancel(); + return; + } + const direction = slideDirection(current2.x, current2.y, touch.pageX, touch.pageY); + if (!(current2.rotated ? direction === 1 || direction === 2 : direction === 3 || direction === 4)) + return; + const distance = current2.rotated ? touch.pageY - current2.y : touch.pageX - current2.x; + const ratio = clamp(distance / size, -1, 1); + const time2 = clamp(current2.time + art.duration * ratio * multiplier, 0, art.duration); + art.seek = time2; + if (!active2(current2)) + return; + art.emit("setBar", "played", clamp(time2 / art.duration, 0, 1), event); + if (active2(current2)) + art.notice.show = `${secondToTime(time2)} / ${secondToTime(art.duration)}`; + }; + return { start, move, cancel }; } function gestureInit(art, events) { - if (isMobile && !art.option.isLive) { - const { $video, $progress } = art.template; - let touchTarget = null; - let isDragging = false; - let startX = 0; - let startY = 0; - let startTime = 0; - const onTouchStart = (event) => { - if (event.touches.length === 1 && !art.isLock) { - if (touchTarget === $progress) { - setCurrentTime(art, event); - } - isDragging = true; - const { pageX, pageY } = event.touches[0]; - startX = pageX; - startY = pageY; - startTime = art.currentTime; - } - }; - const onTouchMove = (event) => { - if (event.touches.length === 1 && isDragging && art.duration) { - const { pageX, pageY } = event.touches[0]; - const direction = GetSlideDirection(startX, startY, pageX, pageY); - const isHorizontal = [3, 4].includes(direction); - const isVertical = [1, 2].includes(direction); - const isLegal = isHorizontal && !art.isRotate || isVertical && art.isRotate; - if (isLegal) { - const ratioX = clamp((pageX - startX) / art.width, -1, 1); - const ratioY = clamp((pageY - startY) / art.height, -1, 1); - const ratio = art.isRotate ? ratioY : ratioX; - const TOUCH_MOVE_RATIO = touchTarget === $video ? art.constructor.TOUCH_MOVE_RATIO : 1; - const currentTime = clamp(startTime + art.duration * ratio * TOUCH_MOVE_RATIO, 0, art.duration); - art.seek = currentTime; - art.emit("setBar", "played", clamp(currentTime / art.duration, 0, 1), event); - art.notice.show = `${secondToTime(currentTime)} / ${secondToTime(art.duration)}`; - } - } - }; - const onTouchEnd = () => { - if (isDragging) { - startX = 0; - startY = 0; - startTime = 0; - isDragging = false; - touchTarget = null; - } - }; - if (art.option.gesture) { - events.proxy($video, "touchstart", (event) => { - touchTarget = $video; - onTouchStart(event); - }); - events.proxy($video, "touchmove", onTouchMove); - } - events.proxy($progress, "touchstart", (event) => { - touchTarget = $progress; - onTouchStart(event); - }); - events.proxy($progress, "touchmove", onTouchMove); - art.on("document:touchend", onTouchEnd); - } + if (!isMobile || art.option.isLive) + return; + const { $video, $progress } = art.template; + const gesture = gestureController(art); + const bind2 = (target) => { + events.proxy(target, "touchstart", (event) => gesture.start(target, event)); + events.proxy(target, "touchmove", (event) => gesture.move(event)); + events.proxy(target, "touchcancel", gesture.cancel); + }; + if (art.option.gesture) + bind2($video); + bind2($progress); } +const documentEvents = [ + "click", + "mouseup", + "keydown", + "touchend", + "touchcancel", + "touchmove", + "mousemove", + "pointerup", + "contextmenu", + "pointermove", + "visibilitychange", + "webkitfullscreenchange" +]; +const windowEvents = ["resize", "scroll", "orientationchange"]; function globalInit(art, events) { - const documentEvents = [ - "click", - "mouseup", - "keydown", - "touchend", - "touchmove", - "mousemove", - "pointerup", - "contextmenu", - "pointermove", - "visibilitychange", - "webkitfullscreenchange" - ]; - const windowEvents = [ - "resize", - "scroll", - "orientationchange" - ]; - const destroyEvents = []; - function bindGlobalEvents(source = {}) { - for (let index = 0; index < destroyEvents.length; index++) { - events.remove(destroyEvents[index]); + let active2; + let generation = 0; + getScope(art).add(() => { + active2 = void 0; + generation++; + return void 0; + }); + const release = (binding) => { + if (binding) { + for (const dispose of binding.disposers) + events.remove(dispose); + binding.disposers.length = 0; } - destroyEvents.length = 0; - const { $player } = art.template; - documentEvents.forEach((name) => { + }; + function bindGlobalEvents(source = {}) { + if (isClosing(art)) + return; + const current2 = ++generation; + const binding = { disposers: [] }; + const cancelled = () => current2 !== generation || isClosing(art); + try { + const { $player } = art.template; const doc = source.document || $player.ownerDocument || document; - const destroy = events.proxy(doc, name, (event) => { - art.emit(`document:${name}`, event); - }); - destroyEvents.push(destroy); - }); - windowEvents.forEach((name) => { const win = source.window || $player.ownerDocument?.defaultView || window; - const destroy = events.proxy(win, name, (event) => { - art.emit(`window:${name}`, event); - }); - destroyEvents.push(destroy); - }); + const register = (target, names, prefix) => { + for (const name of names) { + if (cancelled()) + return; + binding.disposers.push(events.proxy(target, name, (event) => { + if (active2 === binding && !isClosing(art)) + art.emit(`${prefix}:${name}`, event); + })); + } + }; + register(doc, documentEvents, "document"); + register(win, windowEvents, "window"); + } catch (error2) { + release(binding); + throw error2; + } + if (cancelled()) { + release(binding); + return; + } + const previous = active2; + active2 = binding; + release(previous); } bindGlobalEvents(); events.bindGlobalEvents = bindGlobalEvents; @@ -2401,85 +2523,229 @@ function hoverInit(art, events) { events.hover( $player, (event) => { + if (isClosing(art)) + return; addClass($player, "art-hover"); art.emit("hover", true, event); }, (event) => { + if (isClosing(art)) + return; removeClass($player, "art-hover"); art.emit("hover", false, event); } ); } +const states$3 = /* @__PURE__ */ new WeakMap(); +function ownListeners(registry, art) { + states$3.set(registry, { scope: getScope(art), cleaning: false }); +} +function stateOf(registry) { + const state2 = states$3.get(registry); + if (!state2) + throw new Error("ArtPlayer event registry has not been initialized"); + return state2; +} +function proxyListener(registry, target, names, callback, option = {}) { + if (Array.isArray(names)) { + const created = []; + try { + return names.map((name2) => { + const dispose2 = proxyListener(registry, target, name2, callback, option); + created.push(dispose2); + return dispose2; + }); + } catch (error2) { + for (const dispose2 of created.reverse()) { + try { + dispose2(); + } catch (cleanupError) { + console.warn("Failed to roll back event listener:", cleanupError); + } + } + throw error2; + } + } + const name = names; + const state2 = stateOf(registry); + if (state2.scope.closed || state2.cleaning) + return () => { + }; + const options = typeof option === "boolean" ? option : { + capture: Boolean(option?.capture), + once: Boolean(option?.once), + passive: option?.passive, + signal: option?.signal + }; + const capture = typeof options === "boolean" ? options : options.capture; + const signal = typeof options === "boolean" ? void 0 : options.signal; + if (state2.scope.closed || state2.cleaning || signal?.aborted) + return () => { + }; + let active2 = true; + function clean(force = false) { + if (!active2 && !force) + return; + target.removeEventListener(name, callback, capture); + signal?.removeEventListener("abort", dispose); + active2 = false; + registry.destroyEvents.delete(dispose); + } + function dispose() { + clean(); + } + registry.destroyEvents.add(dispose); + try { + target.addEventListener(name, callback, options); + if (!active2 || state2.scope.closed || state2.cleaning) + clean(true); + else if (signal?.aborted) + dispose(); + else + signal?.addEventListener("abort", dispose, { once: true }); + } catch (error2) { + try { + clean(true); + } catch (cleanupError) { + console.warn("Failed to roll back event listener:", cleanupError); + } + throw error2; + } + return dispose; +} +function removeListener(registry, dispose) { + if (!registry.destroyEvents.has(dispose)) + return; + try { + dispose(); + registry.destroyEvents.delete(dispose); + } catch (error2) { + console.warn("Failed to remove event listener:", error2); + } +} +function destroyListeners(registry) { + const state2 = stateOf(registry); + if (state2.cleaning) + return; + state2.cleaning = true; + try { + for (const dispose of registry.destroyEvents) { + try { + dispose(); + registry.destroyEvents.delete(dispose); + } catch (error2) { + console.warn("Failed to destroy event listener:", error2); + } + } + } finally { + state2.cleaning = false; + } +} function moveInit(art, events) { const { $player } = art.template; events.proxy($player, "mousemove", (event) => { - art.emit("mousemove", event); + if (!isClosing(art)) + art.emit("mousemove", event); }); } +function eventSubscriptions(art) { + return (name, callback) => { + if (isClosing(art)) + return; + const listener = (...args) => { + if (!isClosing(art)) + return callback(...args); + }; + art.on(name, listener); + getScope(art).add(() => { + art.off(name, listener); + }); + }; +} function resizeInit(art, events) { const { option, constructor } = art; - art.on("resize", () => { + const on = eventSubscriptions(art); + on("resize", () => { const { aspectRatio: aspectRatio2, notice } = art; - if (art.state === "standard" && option.autoSize) { + if (art.state === "standard" && option.autoSize) art.autoSize(); - } + if (isClosing(art)) + return; art.aspectRatio = aspectRatio2; - notice.show = ""; + if (!isClosing(art)) + notice.show = ""; }); const scope = getScope(art); let cancel = () => { }; - const resizeFn = () => { + const resize = () => { + if (isClosing(art)) + return; cancel(); cancel = timeout(scope, () => art.emit("resize"), constructor.RESIZE_TIME); }; - art.on("window:orientationchange", () => resizeFn()); - art.on("window:resize", () => resizeFn()); - if (screen && screen.orientation && screen.orientation.onchange) { - events.proxy(screen.orientation, "change", () => resizeFn()); - } + on("window:orientationchange", resize); + on("window:resize", resize); + const orientation = art.template.$player.ownerDocument.defaultView?.screen?.orientation; + if (typeof orientation?.addEventListener === "function") + events.proxy(orientation, "change", resize); } function updateInit(art) { - if (art.constructor.USE_RAF) { - const scope = getScope(art); - let cancel = () => { - }; - (function update() { - if (art.playing) { - art.emit("raf"); - } - if (!art.isDestroy) { - cancel = animationFrame(scope, update); - } - })(); - art.on("destroy", () => { - cancel(); - }); - } + if (!art.constructor.USE_RAF) + return; + const scope = getScope(art); + let cancel = () => { + }; + const update = () => { + if (isClosing(art)) + return; + if (art.playing) + art.emit("raf"); + if (!isClosing(art)) + cancel = animationFrame(scope, update); + }; + update(); + eventSubscriptions(art)("destroy", () => cancel()); +} +function inViewport(element, offset) { + const rect = element.getBoundingClientRect(); + const document2 = element.ownerDocument; + const window2 = document2.defaultView; + const height = window2?.innerHeight || document2.documentElement.clientHeight; + const width = window2?.innerWidth || document2.documentElement.clientWidth; + const vertical = rect.top - offset <= height && rect.top + rect.height + offset >= 0; + const horizontal = rect.left - offset <= width + offset && rect.left + rect.width + offset >= 0; + return vertical && horizontal; } function viewInit(art) { - const { - option, - constructor, - template: { $container } - } = art; - const scrollFn = throttle(() => { - art.emit("view", isInViewport($container, constructor.SCROLL_GAP)); - }, constructor.SCROLL_TIME); - art.on("window:scroll", () => scrollFn()); - art.on("view", (state2) => { - if (option.autoMini) { - art.mini = !state2; - } + const { option, constructor, template: { $container } } = art; + const delay = constructor.SCROLL_TIME; + const scope = getScope(art); + const on = eventSubscriptions(art); + let waiting = false; + on("window:scroll", () => { + if (waiting) + return; + art.emit("view", inViewport($container, constructor.SCROLL_GAP)); + if (isClosing(art)) + return; + waiting = true; + timeout(scope, () => { + waiting = false; + }, delay); + }); + on("view", (visible) => { + if (option.autoMini) + art.mini = !visible; }); } -const scopes$2 = /* @__PURE__ */ new WeakMap(); class Events { constructor(art) { this.destroyEvents = /* @__PURE__ */ new Set(); - const scope = getScope(art); - scopes$2.set(this, scope); - scope.add(() => this.destroy()); + ownListeners(this, art); + getScope(art).add(() => { + this.destroy(); + }); this.proxy = this.proxy.bind(this); this.hover = this.hover.bind(this); clickInit(art, this); @@ -2492,116 +2758,142 @@ class Events { updateInit(art); } proxy(target, name, callback, option = {}) { - if (Array.isArray(name)) { - return name.map((item) => this.proxy(target, item, callback, option)); - } - if (scopes$2.get(this).closed) - return () => { - }; - target.addEventListener(name, callback, option); - const destroy = () => target.removeEventListener(name, callback, option); - this.destroyEvents.add(destroy); - return destroy; + return Array.isArray(name) ? proxyListener(this, target, name, callback, option) : proxyListener(this, target, name, callback, option); } hover(target, mouseenter, mouseleave) { - if (mouseenter) { + if (mouseenter) this.proxy(target, "mouseenter", mouseenter); - } - if (mouseleave) { + if (mouseleave) this.proxy(target, "mouseleave", mouseleave); - } } - remove(destroyEvent) { - if (this.destroyEvents.has(destroyEvent)) { - try { - destroyEvent(); - } catch (error2) { - console.warn("Failed to remove event listener:", error2); - } finally { - this.destroyEvents.delete(destroyEvent); - } - } + remove(dispose) { + removeListener(this, dispose); } destroy() { - for (const destroyEvent of this.destroyEvents) { - try { - destroyEvent(); - } catch (error2) { - console.warn("Failed to destroy event listener:", error2); - } - } - this.destroyEvents.clear(); + destroyListeners(this); } } +function defaultHotkeys(art) { + const { constructor } = art; + return { + Escape: () => { + if (art.fullscreenWeb) + art.fullscreenWeb = false; + }, + Space: () => { + silencePromise(art.toggle()); + }, + ArrowLeft: () => { + art.backward = constructor.SEEK_STEP; + }, + ArrowUp: () => { + art.volume += constructor.VOLUME_STEP; + }, + ArrowRight: () => { + art.forward = constructor.SEEK_STEP; + }, + ArrowDown: () => { + art.volume -= constructor.VOLUME_STEP; + } + }; +} +function asElement(target) { + if (target && target.nodeType === 1) + return target; +} +function eventDocument(event, fallback) { + const target = event.target; + return target?.nodeType === 9 ? target : target?.ownerDocument || event.view?.document || fallback; +} +function editable(target) { + const tag = target.tagName.toUpperCase(); + if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") + return true; + return target.isContentEditable; +} +function acceptsHotkey(event, fallback) { + if (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); + while (active2?.shadowRoot?.activeElement) + active2 = asElement(active2.shadowRoot.activeElement); + if (active2 && editable(active2)) + return false; + const first = asElement(event.composedPath?.()[0]) || asElement(event.target); + return !first || !editable(first); +} +const states$2 = /* @__PURE__ */ new WeakMap(); class Hotkey { constructor(art) { this.art = art; this.keys = {}; - if (!isMobile) { + states$2.set(this, { subscribed: false }); + if (!isMobile) this.init(); - } } init() { - const { constructor } = this.art; - if (this.art.option.hotkey) { - this.add("Escape", () => { - if (this.art.fullscreenWeb) { - this.art.fullscreenWeb = false; - } - }); - this.add("Space", () => { - silencePromise(this.art.toggle()); - }); - this.add("ArrowLeft", () => { - this.art.backward = constructor.SEEK_STEP; - }); - this.add("ArrowUp", () => { - this.art.volume += constructor.VOLUME_STEP; - }); - this.add("ArrowRight", () => { - this.art.forward = constructor.SEEK_STEP; - }); - this.add("ArrowDown", () => { - this.art.volume -= constructor.VOLUME_STEP; - }); + const art = this.art; + if (isClosing(art)) + return; + const state2 = states$2.get(this); + if (art.option.hotkey) { + if (!state2.defaults) { + const callbacks = defaultHotkeys(art); + state2.defaults = () => { + for (const key of Object.keys(callbacks)) + this.add(key, callbacks[key]); + }; + } + state2.defaults(); } - this.art.on("document:keydown", (event) => { - if (this.art.isFocus) { - const tag = document.activeElement.tagName.toUpperCase(); - const editable = document.activeElement.getAttribute("contenteditable"); - if (tag !== "INPUT" && tag !== "TEXTAREA" && editable !== "" && editable !== "true" && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { - const events = this.keys[event.code]; - if (events) { - event.preventDefault(); - for (let index = 0; index < events.length; index++) { - events[index].call(this.art, event); - } - this.art.emit("hotkey", event); + if (state2.subscribed) + return; + state2.subscribed = true; + const onKeydown = (event) => { + if (isClosing(art)) + return; + if (art.isFocus && acceptsHotkey(event, art.template.$player.ownerDocument)) { + const callbacks = Object.prototype.hasOwnProperty.call(this.keys, event.code) ? this.keys[event.code] : void 0; + if (callbacks) { + event.preventDefault(); + for (let index = 0; index < callbacks.length; index++) { + if (isClosing(art)) + return; + callbacks[index].call(art, event); } + if (isClosing(art)) + return; + art.emit("hotkey", event); } } - this.art.emit("keydown", event); + if (!isClosing(art)) + art.emit("keydown", event); + }; + art.on("document:keydown", onKeydown); + getScope(art).add(() => { + state2.subscribed = false; + art.off("document:keydown", onKeydown); }); } - add(key, event) { - if (this.keys[key]) { - if (!this.keys[key].includes(event)) { - this.keys[key].push(event); - } + add(key, callback) { + const existing = Object.prototype.hasOwnProperty.call(this.keys, key) ? this.keys[key] : void 0; + if (existing) { + if (!existing.includes(callback)) + existing.push(callback); } else { - this.keys[key] = [event]; + Object.defineProperty(this.keys, key, { value: [callback], enumerable: true, configurable: true, writable: true }); } return this; } - remove(key, event) { - if (this.keys[key]) { - const index = this.keys[key].indexOf(event); - if (index !== -1) { - this.keys[key].splice(index, 1); - } - if (this.keys[key].length === 0) { + remove(key, callback) { + const existing = Object.prototype.hasOwnProperty.call(this.keys, key) ? this.keys[key] : void 0; + if (existing) { + const index = existing.indexOf(callback); + if (index !== -1) + existing.splice(index, 1); + if (existing.length === 0) delete this.keys[key]; - } } return this; } @@ -3114,75 +3406,6 @@ function showMediaUI(art, changes, active2) { art[name].show = value; } } -const current = /* @__PURE__ */ new WeakMap(); -const assignments = /* @__PURE__ */ new WeakMap(); -const sources = /* @__PURE__ */ new WeakMap(); -function getSourceScope(owner) { - return sources.get(owner) || getScope(owner); -} -function captureSource(owner) { - const operation = current.get(owner); - const source = sources.get(owner); - return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed); -} -function beginSource(owner) { - const previous = sources.get(owner); - const source = getScope(owner).child(); - const scope = source.child(); - sources.set(owner, source); - source.add(() => { - if (sources.get(owner) === source) - sources.delete(owner); - }); - const operation = { - scope, - assigned: false, - acceptingEvents: false, - active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation - }; - current.set(owner, operation); - scope.add(() => { - if (current.get(owner) === operation) - current.delete(owner); - operation.onAssigned = void 0; - operation.onError = void 0; - }); - previous?.dispose(); - return operation; -} -function takeAssignment(owner) { - const operation = assignments.get(owner); - assignments.delete(owner); - return operation || beginSource(owner); -} -function finishAssignment(operation) { - operation.assigned = true; - const callback = operation.onAssigned; - operation.onAssigned = void 0; - if (operation.active()) - callback?.(); -} -function assignUrl(owner, operation, url) { - assignments.set(owner, operation); - operation.acceptingEvents = true; - try { - owner.url = url; - } finally { - if (assignments.get(owner) === operation) { - assignments.delete(owner); - finishAssignment(operation); - } - } -} -function failSource(operation, error2) { - if (!operation.active()) - return; - if (operation.onError) - operation.onError(error2); - else - console.warn("Failed to initialize ArtPlayer source:", error2); - operation.scope.dispose(); -} function installEnded(art) { const { option } = art; listenMedia(art, "video:ended", () => { diff --git a/package.json b/package.json index 49681e1fc..0f72b8155 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "ci:build": "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: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": "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 245dadfee..bbb87583c 100644 --- a/packages/artplayer/ARCHITECTURE.md +++ b/packages/artplayer/ARCHITECTURE.md @@ -4,6 +4,132 @@ ArtPlayer keeps its existing constructor, player mixins, plugins and DOM/CSS hoo The production entry is still `src/index.js`; this document marks actual migrated boundaries rather than describing the entire core as TypeScript. +## Keyboard input (CORE-17) + +hotkey.ts retains the art/keys own fields, init/add/remove prototype methods, plain +keys-object prototype, caller-visible callback arrays and chainable registration. +input/hotkey-types.ts describes its minimal generic host and callback receiver; +input/hotkey-defaults.ts creates stable default handlers so repeated init neither +multiplies callbacks nor prevents explicitly restoring removed defaults. Public init +still enables manual mobile keyboard handling; automatic construction stays desktop-only. + +input/keyboard-focus.ts resolves the event document, falls back to the player's current +ownerDocument and follows open shadow focus/composed targets. Native input, textarea, +select, inherited/plaintext editing and IME composition suppress hotkeys while preserving +the generic keydown event. Existing modifier suppression remains. This fixes typing being +intercepted after bindGlobalEvents or inside shadow roots. The global binding itself is +owned by events/globalInit.ts, described below. + +The instance scope removes the one keyboard subscription and callbacks check destruction +before continuing or emitting success. Ordinary synchronous errors still propagate with +their identity. Callback dispatch intentionally retains historical live-array mutation +and this=art semantics. Own-property registration makes prototype-named keys safe without +changing the public keys prototype. Direct editing of those arrays remains observable. + +Run `node --test test/hotkey.test.js test/playback.test.js` and +`yarn test:browser test/browser/hotkey.spec.js`. Browser tests exercise native typing and +play/pause/seek/volume/Escape, iframe and shadow editors, controlled IME and mobile-UA +initialization, and callback destruction. Controlled composition/mobile UA is not physical +keyboard/IME/device certification. Input and scheduling share instance ownership; +the refactor progress record tracks final installed UMD/legacy acceptance. + +## Native listeners and global targets (CORE-17) + +events/index.ts keeps the compatibility facade with the original bound proxy/hover +methods and destroyEvents Set. events/listener-registry.ts owns native registration, +capture snapshots, array rollback, abort and explicit cleanup. Native callback identity +is preserved: direct removeEventListener with the original callback still works. Null +options keep their historical native defaults. Duplicate callbacks retain native +deduplication; disposal is not reference counted. Native once removes the listener itself, +while its bookkeeping remains until explicit disposal or owner cleanup. Abort removes +both the listener and its owned record. Failed removals warn and remain retryable; +a target that permanently refuses removal cannot be forcibly cleaned up. + +events/global-types.ts defines the minimal host, registry and source interfaces. +events/globalInit.ts stages document/window listeners, forwards only from the committed +binding, and retains the old binding if registration fails. A generation counter stops +an interrupted binding from overwriting a newer nested bind; owner destruction prevents +late activation. The original event object, forwarding names, void return and independent +document/window fallback rules remain. Manual Events.destroy still permits later reuse +while the player is alive. events/types.ts composes the typed initializer hosts without +adding runtime fields or changing initializer order. + +Run `node --test test/listener-registry.test.js test/global-events.test.js` and +`yarn test:browser test/browser/listener-registry.spec.js test/browser/global-events.spec.js`. +Tests cover actual iframe targets and native once/abort/callback identity; injected +registration/removal failures exercise cleanup without asserting platform failure rates. + +## Pointer interaction (CORE-17) + +events/clickInit.ts retains synchronous click counting, the inclusive double-click +threshold, live constructor settings and existing desktop/mobile actions. It checks +instance closure after caller callbacks, preventing playback/fullscreen actions after +destruction. input/pointer-focus.ts owns click/contextmenu emitter subscriptions while +preserving isInput's historical INPUT-only meaning and composed-path focus checks. +input/pointer-types.ts keeps host and native registry requirements explicit. + +events/hoverInit.ts and moveInit.ts retain original events and class-before-notification +ordering, with guards against stale callbacks. Emitter listeners still use their explicit +ctx argument; unlike hotkey callbacks, they do not acquire this=art automatically. +Public player methods remain non-configurable and are not replaced by these changes. + +`test/pointer-events.test.js` verifies boundaries, nesting, callback failures, rejected +playback, destruction and owned focus cleanup. `test/browser/pointer-events.spec.js` +compares old/new events, controlled failure paths and actual trusted mouse input with +real media playback. Android UA coverage exercises branch logic, not a physical device. + +## Touch gestures (CORE-17) + +events/gestureInit.ts installs the mobile-only listeners; gesture=false still retains +progress touches and isLive skips gesture installation. input/gesture-controller.ts +owns the active touch, source snapshot and orientation, plus end/cancel/lock subscriptions. +input/gesture-direction.ts preserves the two-pixel threshold and diagonal boundaries; +gesture-types.ts describes the minimal host and drag state. Normal video gestures keep +TOUCH_MOVE_RATIO, progress gestures keep their full-width multiplier and rotated gestures +use the vertical axis. Invalid geometry or a cancelled/replaced session cannot resume +the previous drag. Callback errors retain identity; nested gestures supersede interrupted +work, and destruction prevents subsequent seek/bar/notice writes. + +control/progress/position.ts now accepts a minimal position host and an optional lifetime +predicate between its bar notification and seek. Existing two-argument desktop callers +retain their default behavior. Global events add document:touchcancel with the original +Event payload; its public declaration is additive. Direct local cancellation also works +when document forwarding has been rebound. Source changes cancel through source identity +rather than depending on delayed media events. + +`test/gesture.test.js` covers axes, absolute/relative ordering, reentry, invalid geometry, +source/rotation/lock/finger changes and cleanup. Browser gestures use controlled touch +payloads with actual media and DOM targets. They check requests before first play and +actual seeking after playback initializes the decoder; they do not certify physical +touch delivery, native scrolling arbitration or mobile OS cancellation behavior. + +## Input scheduling and Events facade (CORE-17) + +events/resizeInit.ts retains debounce coalescing, live RESIZE_TIME, normal auto-size, +aspect-ratio restoration and notice cleanup. It guards later writes after caller reentry +and listens to the owner's screen orientation by event capability rather than onchange +being non-null. events/viewInit.ts owns a leading-only throttle, captures SCROLL_TIME at +installation, reads SCROLL_GAP live and preserves synchronous nested dispatch. Its reset +timer and internal subscriptions are released at destruction. Public throttle/debounce +utilities retain their existing independent behavior. + +events/viewport.ts uses the container's current ownerDocument/defaultView, preserving +existing edge and gap arithmetic after iframe adoption. events/updateInit.ts keeps RAF +opt-in, the initial playing emission and one pending owned frame; paused players do not +emit raf, and destruction inside a callback cannot schedule another frame. An explicit +destroy notification still cancels the pending frame while the owner is alive. + +events/subscriptions.ts provides typed, guarded, owner-scoped emitter subscriptions; +scheduling-types.ts describes the event maps and minimal scheduling hosts. The TS Events +facade keeps its own destroyEvents/proxy/hover/bindGlobalEvents properties, prototype +methods, bound proxy/hover behavior and scalar/array disposer returns. It declares the +rebinding property without emitting an extra class field during construction. + +`test/event-scheduling.test.js` verifies debounce/throttle/RAF ownership and reentry. +`test/browser/event-scheduling.spec.js` compares public facade shape, real animation +frames/playback, orientation event capability, timer cleanup and adopted iframe visibility. +Controlled orientation targets do not certify physical device orientation. + ## Display modes (CORE-16, in progress) player/autoSizeMix.ts, autoHeightMix.ts, aspectRatioMix.ts and flipMix.ts retain the diff --git a/packages/artplayer/dist/artplayer.js b/packages/artplayer/dist/artplayer.js index cded353cc..e64148bcc 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{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new l,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 s?t.push(...e.errors):t.push(e)}if(t.length)throw new s(t)}}const c=new WeakMap,d=new WeakMap;function p(t){const e=c.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function u(t){return p(t).scope}function h(t){const e=p(t);return e.destroying||e.scope.closed}function f(t,e,r,n,o=!1){const a=p(t);if(a.destroying||a.scope.closed)return;a.destroying=!0;const i=[],l=t=>{try{t()}catch(e){i.push(...e instanceof s?e.errors:[e])}};n&&t.template?.$video&&l(()=>t.reset()),l(()=>a.scope.dispose()),l(()=>t.template?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(a.releaseContainer?.(),a.releaseContainer=void 0),l(()=>t.emit("destroy")),o&&a.rollback&&l(a.rollback),a.rollback=void 0,a.releaseContainer?.(),a.releaseContainer=void 0;for(const s of i.slice(1))console.warn("Additional ArtPlayer cleanup failure:",s);if(i.length)throw i[0]}const m=new WeakMap;function g(t,e){const r=u(t).child();return m.set(e,r),r}function v(t){const e=m.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function y(t){m.get(t)?.dispose()}function b(t,e){return{on:(r,n)=>{!function(t,e,r,n){const o=v(e);if(o.closed)return;const a=(...t)=>{if(!o.closed)return n(...t)};t.on(r,a),o.add(()=>{t.off(r,a)})}(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const a=v(e);if(a.closed)return()=>{};const i=t.events.proxy(r,n,t=>{if(!a.closed)return o(t)});return a.add(()=>{t.events.remove(i)})}(t,e,r,n,o)}}const w=globalThis?.CUSTOM_USER_AGENT??("undefined"!==typeof navigator?navigator.userAgent:""),x=/^(?:(?!chrome|android).)*safari/i.test(w),k=/iPad|iPhone|iPod/i.test(w)&&!window.MSStream,$=k||w.includes("Macintosh")&&navigator.maxTouchPoints>=1,E=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(w)||$,T="undefined"!==typeof window&&"undefined"!==typeof document;function C(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function L(t,e=document){return e.querySelector(t)}function S(t,e=document){return Array.from(e.querySelectorAll(t))}function P(t,e){return t.classList.add(e)}function M(t,e){return t.classList.remove(e)}function z(t,e){return t.classList.contains(e)}function A(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function R(t,e,r){return t.style[e]=r,t}function O(t,e){for(const r in e)R(t,r,e[r]);return t}function I(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function _(t,e){I(t).forEach(t=>M(t,e)),P(t,e)}function N(t,e,r="top"){E||(t.setAttribute("aria-label",e),P(t,"hint--rounded"),P(t,`hint--${r}`))}function D(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,a=r.top-e<=n&&r.top+r.height+e>=0,i=r.left-e<=o+e&&r.left+r.width+e>=0;return a&&i}function W(t,e){return q(t).includes(e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function V(t){return document.createElement(t)}function Y(t="",e=""){const r=V("i");return P(r,"art-icon"),P(r,`art-icon-${t}`),A(r,e),r}function B(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function H(t){return t.getBoundingClientRect()}function j(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const a=document.createElement("canvas"),i=a.getContext("2d");a.width=o.width*e,a.height=o.height*e,i.drawImage(o,0,0,a.width,a.height),a.toBlob(e=>{const o=URL.createObjectURL(e),a=new Image;a.onload=function(){r(a)},a.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},a.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function q(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function U(){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;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class X extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function G(t,e){if(!t)throw new X(e);return t}function K(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function Z(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function J(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 Q(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function tt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function et(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 rt={"&":"&","<":"<",">":">","'":"'",'"':"""},nt={"&":"&","<":"<",">":">","'":"'",""":'"'},ot=/(&|<|>|'|")/g;function at(t){return t.replace(/[&<>'"]/g,t=>rt[t]||t)}const it=Object.defineProperty,{hasOwnProperty:st}=Object.prototype;function lt(t,e){return st.call(t,e)}function ct(t,e){return Object.getOwnPropertyDescriptor(t,e)}function dt(...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],a=r[n];let i;i=Array.isArray(o)&&Array.isArray(a)?o.concat(...a):e(o)&&e(a)?dt(o,a):a,it(t,n,{value:i,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function pt(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 ht(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="",a="",,,i=""]=n;return{start:r(o.trim()),end:r(a.trim()),text:i.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")}`}function ft(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}}const mt=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:X,addClass:P,append:A,assToVtt:ht,capitalize:tt,clamp:Q,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:J,errorHandle:G,escape:at,get:ct,getComposedPath:q,getExt:Z,getIcon:Y,getRect:H,getSafeAreaInsets:U,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:lt,hasClass:z,includeFromEvent:W,inverseClass:_,isBrowser:T,isIOS:k,isIOS13:$,isInViewport:D,isMobile:E,isSafari:x,loadImg:j,mergeDeep:dt,query:L,queryAll:S,remove:function(t){return t.parentNode.removeChild(t)},removeClass:M,replaceElement:F,secondToTime:et,setStyle:R,setStyleText:C,setStyles:O,siblings:I,silencePromise:K,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:pt,supportsFlex:B,throttle:ft,tooltip:N,unescape:function(t){return t.replace(ot,t=>nt[t]||t)},userAgent:w,vttToBlob:ut},Symbol.toStringTag,{value:"Module"}));function gt(t,e){return A(t,e)}function vt(t,e){return e.querySelector(t)}const yt="array",bt="boolean",wt="string",xt="number",kt="object",$t="function";function Et(t,e,r){return G(e===wt||e===xt||t instanceof Element,`${r.join(".")} require '${wt}' or 'Element' type`)}const Tt={html:Et,disable:`?${bt}`,name:`?${wt}`,index:`?${xt}`,style:`?${kt}`,click:`?${$t}`,mounted:`?${$t}`,tooltip:`?${wt}|${xt}`,width:`?${xt}`,selector:`?${yt}`,onSelect:`?${$t}`,switch:`?${bt}`,onSwitch:`?${$t}`,range:`?${yt}`,onRange:`?${$t}`,onChange:`?${$t}`},Ct={id:wt,container:Et,url:wt,poster:wt,type:wt,theme:wt,lang:wt,volume:xt,isLive:bt,muted:bt,autoplay:bt,autoSize:bt,autoMini:bt,loop:bt,flip:bt,playbackRate:bt,aspectRatio:bt,screenshot:bt,setting:bt,hotkey:bt,pip:bt,mutex:bt,backdrop:bt,fullscreen:bt,fullscreenWeb:bt,subtitleOffset:bt,miniProgressBar:bt,useSSR:bt,playsInline:bt,lock:bt,gesture:bt,fastForward:bt,autoPlayback:bt,autoOrientation:bt,airplay:bt,proxy:`?${$t}`,plugins:[$t],layers:[Tt],contextmenu:[Tt],settings:[Tt],controls:[{...Tt,position:(t,e,r)=>{const n=["top","left","right"];return G("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${bt}`,html:wt,url:wt}],highlight:[{time:xt,text:wt}],thumbnails:{url:wt,number:xt,column:xt,width:xt,height:xt,scale:xt},subtitle:{url:wt,name:wt,type:wt,style:kt,escape:bt,encoding:wt,onVttLoad:$t},moreVideoAttr:kt,i18n:kt,icons:kt,cssVar:kt,customType:kt},Lt=new WeakSet;class St{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 z(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?P(e,r):M(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t;if(h(this.art))return;if(e.html=e.html||"",o(e,Tt),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;G(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const a=document.createElement("div"),i=g(this.art,a),s=[],l=Object.getOwnPropertyDescriptor(this,r);let c=!1;i.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(i.closed)return;if(function(t,e,r,n,o,a){P(t,`art-${r}`),P(t,`art-${r}-${n}`);const i=Array.from(e.children);t.dataset.index=String(a.index||o);const s=i.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):A(e,t),a.html&&A(t,a.html),a.style&&O(t,a.style),a.tooltip&&N(t,a.tooltip)}(a,this.$parent,this.name,r,this.id,e),i.closed)return;if(e.click){const t=this.art.events.proxy(a,"click",t=>{i.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,a,s),i.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,a),c=!0,n.set(r,{$ref:a,events:s,option:e}),e.mounted&&e.mounted.call(this.art,a),a}catch(d){try{y(a)}catch(p){console.warn("ArtPlayer component cleanup failed:",p)}throw n.get(r)?.$ref===a&&n.delete(r),c&&this[r]===a&&(l?Object.defineProperty(this,r,l):delete this[r]),a.remove(),d}}remove(t){G(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Lt.has(e)){Lt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{y(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Lt.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 Pt extends St{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,g(t,this.$parent),E||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=b(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}=b(e,t),n=L('[data-value="1"]',t);n&&_(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&_(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}=b(e,t),n=L('[data-value="default"]',t);n&&_(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(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(tt(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}=b(e,t),n=L('[data-value="normal"]',t);n&&_(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(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 ${a}`}}({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 a=0;a{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:a,width:i,left:s,top:l}=H(e),{height:c,width:d}=H(r);let p=n-s,u=o-l;n+d>s+i&&(p=i-d),o+c>l+a&&(u=a-c),O(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{W(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Mt(t,e,r,n,o={}){const{capture:a=!1,once:i=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let l=()=>{};function c(e){i&&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,a)}finally{s?.removeEventListener("abort",l)}}),s?.addEventListener("abort",l,{once:!0}),l}function zt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const a=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(a)}),o}function At(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const a=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(a),n||r(!1)})})}function Rt(t,e){const{$progress:r}=t.template,{left:n}=H(r),o=Q((E?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),a=o/r.clientWidth*t.duration;return{second:a,time:et(a),width:o,percentage:Q(o/r.clientWidth,0,1)}}function Ot(t,e){if(t.isRotate){const r=(e.touches[0].clientY-t.top)/t.height,n=r*t.duration;t.emit("setBar","played",r,e),t.seek=n}else{const{second:r,percentage:n}=Rt(t,e);t.emit("setBar","played",n,e),t.seek=r}}function It(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,a=v(e),{on:i}=b(t,e);let s=()=>{};const l=vt(".art-progress-hover",e),c=vt(".art-progress-loaded",e),d=vt(".art-progress-played",e),p=vt(".art-progress-highlight",e),u=vt(".art-progress-indicator",e),h=vt(".art-progress-tip",e);function f(r,n){const{width:o,time:a}=n||Rt(t,r);h.textContent=a||"00:00";const i=h.clientWidth;o<=i/2?R(h,"left",0):o>e.clientWidth-i/2?R(h,"left",e.clientWidth-i+"px"):R(h,"left",o-i/2+"px")}r.indicator?A(u,r.indicator):R(u,"backgroundColor","var(--art-theme)"),i("setBar",function(r,n,i){const m="played"===r&&i&&E;if("loaded"===r&&R(c,"width",100*n+"%"),"hover"===r&&(R(l,"width",100*n+"%"),W(i,p)?function(r){const{width:n}=Rt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const a=h.clientWidth;n<=a/2?R(h,"left",0):n>e.clientWidth-a/2?R(h,"left",e.clientWidth-a+"px"):R(h,"left",n-a/2+"px")}(i):f(i),0===n?M(o,"art-progress-hover"):P(o,"art-progress-hover")),"played"===r&&(R(d,"width",100*n+"%"),R(u,"left",100*n+"%")),m){P(o,"art-progress-hover");f(i,{width:e.clientWidth*n,time:et(n*t.duration)}),s(),s=zt(a,()=>{M(o,"art-progress-hover")},500)}}),i("video:loadedmetadata",function(){p.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(i("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),i("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),i("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function _t(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{It(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:a}=b(t,e);if(!E){let e=!1;a(r,"click",e=>{e.target!==n&&Ot(t,e)}),a(r,"mousemove",e=>{const{percentage:r}=Rt(t,e);t.emit("setBar","hover",r,e)}),a(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),a(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=Rt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function Nt(t){const{option:e}=t.art;e.isLive||t.add(_t({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}=b(e,t),{icons:o,i18n:a}=e,i=gt(t,o.play),s=gt(t,o.pause);function l(){R(i,"display","flex"),R(s,"display","none")}function c(){R(i,"display","none"),R(s,"display","flex")}N(i,a.get("Play")),N(s,a.get("Pause")),n(i,"click",()=>{K(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}=b(e,t),{icons:o}=e,a=gt(t,o.volume),i=gt(t,o.volumeClose),s=gt(t,'
'),l=gt(s,'
'),c=gt(l,'
'),d=gt(l,'
'),p=gt(d,'
'),u=gt(p,'
'),h=gt(d,'
');function f(t){const{top:e,height:r}=H(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)R(a,"display","none"),R(i,"display","flex"),R(h,"top","100%"),R(u,"top","100%"),c.textContent="0";else{const t=100*e.volume;R(a,"display","flex"),R(i,"display","none"),R(h,"top",100-t+"%"),R(u,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(a,"click",()=>{e.muted=!0}),n(i,"click",()=>{e.muted=!1}),E)R(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=>({...t,style:E?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=b(e,t);function n(){const r=`${et(e.currentTime)} / ${et(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!u(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!E&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=b(e,t),{icons:n}=e;gt(t,n.screenshot),r(t,"click",()=>{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}=b(e,t),{icons:o,i18n:a}=e;gt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{N(t,a.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}=b(e,t),{icons:o,i18n:a}=e;gt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{N(t,a.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}=b(e,t),{icons:n}=e;gt(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}=b(e,t),{icons:o,i18n:a}=e,i=gt(t,o.fullscreenWebOn),s=gt(t,o.fullscreenWebOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(N(t,a.get("Exit Web Fullscreen")),R(i,"display","none"),R(s,"display","inline-flex")):(N(t,a.get("Web Fullscreen")),R(i,"display","inline-flex"),R(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}=b(e,t),{icons:o,i18n:a}=e,i=gt(t,o.fullscreenOn),s=gt(t,o.fullscreenOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(N(t,a.get("Exit Fullscreen")),R(i,"display","none"),R(s,"display","inline-flex")):(N(t,a.get("Fullscreen")),R(i,"display","inline-flex"),R(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rWt.get(t).option.selector}),it(t,"$control_item",{get:()=>Wt.get(t).item}),it(t,"$control_value",{get:()=>Wt.get(t).value})),Wt.set(t,e)}function Vt(t,e){t.innerHTML=e}function Yt(t,e,r,n,o){const{proxy:a}=t.events,i=v(n),s=r.selector;P(n,"art-control-selector");const l=document.createElement("div");P(l,"art-selector-value"),A(l,r.html),n.textContent="",A(n,l);const c=gt(n,'
');for(let u=0;u{if(i.closed)return;const o=q(n),a=r.selector.find(t=>o.includes(t.$control_item));if(!a)return;const s=++d,c=()=>!i.closed&&s===d,p=i.add(function(t,e){return Dt.set(t,e),()=>{Dt.get(t)===e&&Dt.delete(t)}}(n,c));try{if(e(a),i.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,a,a.$control_item,n);c()&&Vt(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Bt extends St{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;g(t,n);const{on:o}=b(t,n);o("mousemove",()=>{E||(this.show=!0)}),o("click",()=>{E?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=W(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?(M(r,"art-hide-cursor"),P(r,"art-hover"),this.timer=Date.now()):(P(r,"art-hide-cursor"),M(r,"art-hover"))}),this.init(),u(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=v(e),{on:a}=b(t,e),i=()=>{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(a("resize",i),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(i);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(i);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}i()}(t)}init(){Nt(this)}add(t){if(h(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:G(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Vt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Ht(t,e,r,n){const o=e-n,a=r-t;let i=0;if(Math.abs(a)<2&&Math.abs(o)<2)return i;const s=function(t,e){return 180*Math.atan2(e,t)/Math.PI}(a,o);return s>=-45&&s<45?i=4:s>=45&&s<135?i=1:s>=-135&&s<-45?i=2:(s>=135&&s<=180||s>=-180&&s<-135)&&(i=3),i}function jt(t){if(t.constructor.USE_RAF){const e=u(t);let r=()=>{};!function n(){t.playing&&t.emit("raf"),t.isDestroy||(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))}(),t.on("destroy",()=>{r()})}}const qt=new WeakMap;class Ut{constructor(t){this.destroyEvents=new Set;const e=u(t);qt.set(this,e),e.add(()=>this.destroy()),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),function(t,e){const{constructor:r,template:{$player:n,$video:o}}=t;function a(e){W(e,n)?(t.isInput="INPUT"===e.target.tagName,t.isFocus=!0,t.emit("focus",e)):(t.isInput=!1,t.isFocus=!1,t.emit("blur",e))}t.on("document:click",a),t.on("document:contextmenu",a);let i=[];e.proxy(o,"click",e=>{const n=Date.now();i.push(n);const{MOBILE_CLICK_PLAY:o,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=i.filter(t=>n-t<=a);switch(c.length){case 1:t.emit("click",e),E?!t.isLock&&o&&K(t.toggle()):K(t.toggle()),i=c;break;case 2:t.emit("dblclick",e),E?!t.isLock&&s&&K(t.toggle()):l&&(t.fullscreen=!t.fullscreen),i=[];break;default:i=[]}})}(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{P(r,"art-hover"),t.emit("hover",!0,e)},e=>{M(r,"art-hover"),t.emit("hover",!1,e)})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t;t.on("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),t.aspectRatio=e,n.show=""});const o=u(t);let a=()=>{};const i=()=>{a(),a=zt(o,()=>t.emit("resize"),n.RESIZE_TIME)};t.on("window:orientationchange",()=>i()),t.on("window:resize",()=>i()),screen&&screen.orientation&&screen.orientation.onchange&&e.proxy(screen.orientation,"change",()=>i())}(t,this),function(t,e){if(E&&!t.option.isLive){const{$video:r,$progress:n}=t.template;let o=null,a=!1,i=0,s=0,l=0;const c=e=>{if(1===e.touches.length&&!t.isLock){o===n&&Ot(t,e),a=!0;const{pageX:r,pageY:c}=e.touches[0];i=r,s=c,l=t.currentTime}},d=e=>{if(1===e.touches.length&&a&&t.duration){const{pageX:n,pageY:a}=e.touches[0],c=Ht(i,s,n,a),d=[3,4].includes(c),p=[1,2].includes(c);if(d&&!t.isRotate||p&&t.isRotate){const c=Q((n-i)/t.width,-1,1),d=Q((a-s)/t.height,-1,1),p=t.isRotate?d:c,u=o===r?t.constructor.TOUCH_MOVE_RATIO:1,h=Q(l+t.duration*p*u,0,t.duration);t.seek=h,t.emit("setBar","played",Q(h/t.duration,0,1),e),t.notice.show=`${et(h)} / ${et(t.duration)}`}}},p=()=>{a&&(i=0,s=0,l=0,a=!1,o=null)};t.option.gesture&&(e.proxy(r,"touchstart",t=>{o=r,c(t)}),e.proxy(r,"touchmove",d)),e.proxy(n,"touchstart",t=>{o=n,c(t)}),e.proxy(n,"touchmove",d),t.on("document:touchend",p)}}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=ft(()=>{t.emit("view",D(n,r.SCROLL_GAP))},r.SCROLL_TIME);t.on("window:scroll",()=>o()),t.on("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){const r=["click","mouseup","keydown","touchend","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],n=["resize","scroll","orientationchange"],o=[];function a(a={}){for(let t=0;t{const n=a.document||i.ownerDocument||document,s=e.proxy(n,r,e=>{t.emit(`document:${r}`,e)});o.push(s)}),n.forEach(r=>{const n=a.window||i.ownerDocument?.defaultView||window,s=e.proxy(n,r,e=>{t.emit(`window:${r}`,e)});o.push(s)})}a(),e.bindGlobalEvents=a}(t,this),jt(t)}proxy(t,e,r,n={}){if(Array.isArray(e))return e.map(e=>this.proxy(t,e,r,n));if(qt.get(this).closed)return()=>{};t.addEventListener(e,r,n);const o=()=>t.removeEventListener(e,r,n);return this.destroyEvents.add(o),o}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){if(this.destroyEvents.has(t))try{t()}catch(e){console.warn("Failed to remove event listener:",e)}finally{this.destroyEvents.delete(t)}}destroy(){for(const e of this.destroyEvents)try{e()}catch(t){console.warn("Failed to destroy event listener:",t)}this.destroyEvents.clear()}}class Xt{constructor(t){this.art=t,this.keys={},E||this.init()}init(){const{constructor:t}=this.art;this.art.option.hotkey&&(this.add("Escape",()=>{this.art.fullscreenWeb&&(this.art.fullscreenWeb=!1)}),this.add("Space",()=>{K(this.art.toggle())}),this.add("ArrowLeft",()=>{this.art.backward=t.SEEK_STEP}),this.add("ArrowUp",()=>{this.art.volume+=t.VOLUME_STEP}),this.add("ArrowRight",()=>{this.art.forward=t.SEEK_STEP}),this.add("ArrowDown",()=>{this.art.volume-=t.VOLUME_STEP})),this.art.on("document:keydown",t=>{if(this.art.isFocus){const e=document.activeElement.tagName.toUpperCase(),r=document.activeElement.getAttribute("contenteditable");if("INPUT"!==e&&"TEXTAREA"!==e&&""!==r&&"true"!==r&&!t.altKey&&!t.ctrlKey&&!t.metaKey&&!t.shiftKey){const e=this.keys[t.code];if(e){t.preventDefault();for(let r=0;r\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 Jt{constructor(t){const e={...Zt,...t.option.icons};for(const r in e)it(this,r,{get:()=>Y(r,e[r])})}}class Qt extends St{constructor(t){super(t),this.name="info",E||this.init()}init(){const{proxy:t,constructor:e,template:{$infoPanel:r,$infoClose:n,$video:o}}=this.art;t(n,"click",()=>{this.show=!1});let a=()=>{};const i=S("[data-video]",r)||[];this.art.on("destroy",()=>a());const s=u(this.art);!function t(){for(let e=0;e{R(o,"display","none"),R(a,"display",null)}),n.proxy(e.$state,"click",()=>K(t.play()))}}class ne{constructor(t){this.art=t,this.timer=null,u(t).add(()=>this.destroy()),t.on("destroy",()=>this.destroy())}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}set show(t){if(u(this.art).closed)return;const{constructor:e,template:{$player:r,$noticeInner:n}}=this.art;t?(n.textContent=t instanceof Error?t.message.trim():t,P(r,"art-notice-show"),clearTimeout(this.timer),this.timer=setTimeout(()=>{n.textContent="",M(r,"art-notice-show")},e.NOTICE_TIME)):M(r,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function oe({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function ae(t,e){if(!oe(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 oe(r)?r:void 0}function ie(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(h(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!oe(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||h(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function se(t,e,r,n=!1){const o=e=>{h(t)||r(e)};t[n?"once":"on"](e,o),u(t).add(()=>{t.off(e,o)})}function le(t,e,r){for(const[n,o]of e){if(h(t)||r&&!r())return;t[n].show=o}}const ce=new WeakMap,de=new WeakMap,pe=new WeakMap;function ue(t){return pe.get(t)||u(t)}function he(t){const e=ce.get(t),r=pe.get(t);return()=>ce.get(t)===e&&(!e||e.active())&&pe.get(t)===r&&(!r||!r.closed)}function fe(t){const e=pe.get(t),r=u(t).child(),n=r.child();pe.set(t,r),r.add(()=>{pe.get(t)===r&&pe.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!h(t)&&!n.closed&&ce.get(t)===o};return ce.set(t,o),n.add(()=>{ce.get(t)===o&&ce.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function me(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function ge(t,e,r){de.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{de.get(t)===e&&(de.delete(t),me(e))}}function ve(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function ye(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:a}}=t;let i,s=ue(t),l=0;return{reset(){l=0,i?.dispose(),M(a,"art-error")},loadStart(){M(a,"art-error")},schedule(c){(async c=>{if(h(t))return;const d=ue(t);if(d!==s&&(s=d,l=0),i&&!i.closed)return;const p=d.child();i=p,p.add(()=>{i===p&&(i=void 0)});const u=()=>!h(t)&&!p.closed&&d===ue(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function be(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{h(t)||t.emit(`video:${e.type}`,e)})}(t);const e=ye(t);!function(t,e){se(t,"video:canplay",()=>{e.reset(),le(t,[["loading",!1]])}),se(t,"video:canplay",()=>{le(t,[["loading",!1],["controls",!0],["mask",!0]]),h(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=he(t);if(t.seek=0,h(t)||!e())return;K(t.play()),e()&&le(t,[["controls",!1],["mask",!1]],e)}else le(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"),E&&le(t,[["loading",!1],["controls",!0],["mask",!0]])}),se(t,"video:loadstart",()=>{e.loadStart(),le(t,[["loading",!0],["mask",!1],["controls",!0]])}),se(t,"video:pause",()=>{le(t,[["controls",!0],["mask",!0]])}),se(t,"video:play",()=>{le(t,[["mask",!1]]),h(t)||R(r,"display","none")}),se(t,"video:playing",()=>le(t,[["mask",!1]])),se(t,"video:progress",()=>{t.playing&&le(t,[["loading",!1]])}),se(t,"video:seeked",()=>le(t,[["loading",!1],["mask",!0]])),se(t,"video:seeking",()=>le(t,[["loading",!0],["mask",!1]])),se(t,"video:timeupdate",()=>le(t,[["mask",!1]])),se(t,"video:waiting",()=>le(t,[["loading",!0],["mask",!1]]))}(t,e)}const we=[["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"]],xe=(()=>{if("undefined"===typeof document)return!1;const t=we[0],e={};for(const r of we){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),ke={change:xe.fullscreenchange,error:xe.fullscreenerror},$e={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{$e.off("change",o),r()};$e.on("change",o);const a=t[xe.requestFullscreen](e);a instanceof Promise&&a.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!$e.isFullscreen)return void t();const r=()=>{$e.off("change",r),t()};$e.on("change",r);const n=document[xe.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>$e.isFullscreen?$e.exit():$e.request(t,e),onchange(t){$e.on("change",t)},onerror(t){$e.on("error",t)},on(t,e){const r=ke[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=ke[t];r&&document.removeEventListener(r,e,!1)},raw:xe};function Ee(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($e,{isFullscreen:{get:()=>Boolean(document[xe.fullscreenElement])},element:{enumerable:!0,get:()=>document[xe.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[xe.fullscreenEnabled])}});const Te=new WeakMap;function Ce(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function Le(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:a}=t,i=function(t,e,r){let n=Te.get(t);if(!n){n=new WeakMap,Te.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Ce(n))})}return n}(e,r,n);i.set(o,a),t.element===o&&(i.delete(o),Ce(a))}function Se(t,e,r,n,o=()=>t.element!==t.target){const a=e.child();let i,s,l=!1,c=!1,d=!1,p=!1,u=!1;const h=new Promise((t,e)=>{i=t,s=e});function f(t=!1,e){if(!l){l=!0;try{a.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):i()}}a.add(()=>{l||(l=!0,c=!0,i(),d&&!p&&r&&Le(t))});const m=()=>{d&&!p&&(r?t.element===t.target:o())&&f()};if(Mt(a,t.document,t.changeEvent,m),Mt(a,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(u=!0,d&&!p&&f(!0,new Error("Fullscreen request failed")))}),!a.closed)try{r&&function(t){Te.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&&Le(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:()=>a.dispose()}}function Pe(t,e){const r=u(t).child(),{$player:n,$video:o}=t.template,a=()=>e.element===n||e.element===o;let i,s=a(),l=0,c=s,d=!1,p=!1,f=!1;function m(){if(a())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),m()}),Mt(r,e.document,e.changeEvent,()=>{const r=a();if(r&&function(t){return Te.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void m();if(r===s||h(t))return;s=r;const o=l,i=()=>h(t)||a()!==r||o!==l&&c!==r;t.emit("fullscreen",r),i()||(r&&(t.state="fullscreen"),i()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),Mt(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(f||void 0!==i||a()))&&!h(t)&&t.emit("fullscreenError",r)}),{get:()=>!h(t)&&a(),set(n){if(h(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?p=!1:d&&(p=!0),i?.cancel(),i=void 0,d=!1,!c&&!a())return Promise.resolve();f=!0,d=c;const s=Se(e,r,c,()=>{!h(t)&&c||m()},()=>!a());f=!1,l===o?i=s:s.cancel();const u=s.promise.catch(e=>{throw h(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(i=void 0,d=!1)});return u.catch(()=>{}),u}}}const Me=new WeakSet;function ze(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Ae(t){Me.delete(t),t.removeEventListener("webkitbeginfullscreen",Re),t.removeEventListener("webkitpresentationmodechanged",Re)}function Re(t){if(Me.has(this)&&ze(this,"webkitbeginfullscreen"===t.type)){Ae(this);try{this.webkitExitFullscreen?.()}catch{}}}function Oe(t){Me.add(t),t.addEventListener("webkitbeginfullscreen",Re),t.addEventListener("webkitpresentationmodechanged",Re)}function Ie(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=ze(e),a=o,i=!1,s=0;const l=()=>ze(e,n);function c(r){if(h(t)||(c=e,Me.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(i=!1),d===o)return;o=d;const p=s,u=()=>h(t)||l()!==d||p!==s&&a!==d;t.emit("fullscreen",d),u()||(d&&(t.state="fullscreen"),u()||t.emit("resize"))}r.add(()=>{s++,a=!1,i&&Oe(e),l()&&e.webkitExitFullscreen?.()}),Mt(r,e,"webkitbeginfullscreen",()=>c(!0)),Mt(r,e,"webkitendfullscreen",()=>c(!1)),Mt(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!h(t)&&l(),set(r){if(h(t))return;const n=++s;if(a=Boolean(r),r){if(Ae(e),t.state="fullscreen",h(t)||n!==s)return;i=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(i=!1),o}}else i&&(i=!1,Oe(e)),l()&&e.webkitExitFullscreen()}}}function _e(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,a=()=>{if(h(t))return;const a=function(t){const e=$e.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:()=>Ee(t,e.requestFullscreen,void 0),exit:()=>Ee(r,e.exitFullscreen)}}(o);a?it(t,"fullscreen",Pe(t,a)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",Ie(t)):it(t,"fullscreen",{get:()=>!1,set(){h(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",ct(t,"fullscreen"))};t.once("video:loadedmetadata",a),u(t).add(()=>{t.off("video:loadedmetadata",a)})}function Ne(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function De({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 We(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()&&(De(t.placement),r()))}return u(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(a){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(i){throw new s([a,i])}throw a}}),a=>{if(h(t))return;const i=++n,s=()=>i===n&&!h(t);if(a){r||(r={placement:Ne(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 Fe(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 Ve(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Ye(t,e,r,n){const o=e.child();if(o.closed)return;const a=t.template.$mini;if(a){const t=a.style.display;return o.add(()=>{a.style.display=t}),{element:a,cancelDrag:()=>{},fresh:!1}}const i=t.template.$player.ownerDocument,s=i.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=i.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const a=i.createElement("div");a.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;a.append(l,c),s.append(e,a),Mt(o,e,"click",n),Mt(o,l,"click",()=>{K(t.play())}),Mt(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,a=0,i=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};Mt(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,a=e.clientX,i=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-a}px, ${t.clientY-i}px)`)},c=()=>{if(r.closed||!o||!n())return;const a=e.getBoundingClientRect(),i=Fe(a.left,a.top,Ve(e));s(),e.style.left=`${i.left}px`,e.style.top=`${i.top}px`,t.storage.set("left",i.left),r.closed||t.storage.set("top",i.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,i.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 Be(t){const{$player:e,$video:r}=t.template,n=u(t).child();let o,a,i=0,s=!1,l=!1;const c=()=>!h(t)&&e.classList.contains("art-mini");function d(){if(a){const e=a,r=i;a=void 0;try{De(e)}catch(t){throw r!==i||a||(a=e),t}}}function p(){if(h(t))return;const r=++i;l=!1,d(),h(t)||r!==i||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(h(t))return;const u=++i;if(s)l=!0;else if(t.state="mini",!h(t)&&u===i){a??(a=Ne(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Ye(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void f();if(!o||h(t))return;if(u!==i)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),h(t)||u!==i)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),a=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}:{...Fe(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,Ve(o.element));if(h(t)||u!==i)return;if(o.element.style.left=`${a.left}px`,o.element.style.top=`${a.top}px`,a.reset){if(t.storage.set("top",a.top),h(t)||u!==i)return;t.storage.set("left",a.left)}h(t)||u!==i||t.emit("mini",!0)}catch(m){const r=l;throw l=!1,h(t)||u!==i&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),m}}}return n.add(()=>{i++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?f():p()}}}const He=new WeakSet,je=t=>"picture-in-picture"===t.webkitPresentationMode;function qe(t){He.delete(t),t.removeEventListener("webkitpresentationmodechanged",Ue),t.removeEventListener("enterpictureinpicture",Ue)}function Ue(){if(He.has(this)&&je(this)){qe(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function Xe(t){He.add(t),t.addEventListener("webkitpresentationmodechanged",Ue),t.addEventListener("enterpictureinpicture",Ue)}function Ge(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=u(t).child(),o=()=>r.pictureInPictureElement===e;let a=o(),i=a,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function p(e,r,n){e.then(()=>{!r||!h(t)&&i||d()},e=>{h(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,i=!1,d()}),Mt(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||a)return;const e=c;t.state="pip",!h(t)&&e===c&&o()&&(a=!0,t.emit("pip",!0))}),Mt(n,e,"leavepictureinpicture",()=>{a&&!o()&&(a=!1,t.emit("pip",!1))}),{get:()=>!h(t)&&o()?e:null,set(n){if(h(t))return;const a=++c;if(i=Boolean(n),i?l=!1:s&&(l=!0),s=!1,i){if(t.state="pip",h(t)||c!==a)return;s=!0;try{p(e.requestPictureInPicture(),!0,a)}catch(d){throw c===a&&(s=!1),d}}else o()&&p(r.exitPictureInPicture(),!1,a)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=!1,a=0,i=0;function s(r=!1){if(h(t)||He.has(e))return;const s=je(e);if(s&&(o=!1),s===n&&!r)return;const l=a;s&&(t.state="pip"),h(t)||a!==l||je(e)!==s||(n=s,i++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{a++,o&&Xe(e),je(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Mt(r,e,l,()=>s());return{get:()=>!h(t)&&je(e),set(r){if(h(t))return;const n=++a,l=i;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(qe(e),t.state="pip",h(t)||a!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===a&&(o=!1),c}}else o&&(o=!1,Xe(e)),je(e)&&e.webkitSetPresentationMode("inline");h(t)||n!==a||l!==i||je(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){h(t)||(r.show=e.get("PIP Not Supported"))}})}function Ke(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,a=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:a?.html||"",selector:e,async onSelect(e,r,a){const i=function(t){return t&&Dt.get(t)||(()=>!0)}(a);if(await t.switchQuality(e.url),!h(t)&&i()){const r=`${o.get("Switch Video")}: ${e.html}`;!h(t)&&i()&&(n.show=r)}return e.html}})}})}function Ze(t,e,r,n,o=!0){let a,i=!1;const s=e=>{t.closed||i||(o&&(i=!0,a()),n(e))};return e[o?"once":"on"](r,s),a=t.add(()=>{e.off(r,s)}),s}function Je(t,e,r){return new Promise((n,o)=>{if(h(t)||e===t.url)return void n();const a=fe(t),i=a.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,a.onError=void 0,a.onAssigned=void 0,i.dispose(),t?o(e):n(),t&&a.scope.dispose())};i.add(()=>{l()});const c=()=>!s&&a.active(),d=t=>l(!0,t);a.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=i.child(),u={"video:error":d,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){d(e)}},"video:canplay":()=>{if(!c())return;p.dispose();(async()=>{if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}})().catch(d)}},h=i.child(),f=[],m=Object.keys(u);for(const e of m)Ze(h,t,e,t=>{a.acceptingEvents&&f.push([e,t])},!1);if(ge(t,a,e),!c())return;if(t.notice.show="",!c())return;const g=()=>{if(h.dispose(),!e)return void l();const r={};for(const e of m)r[e]=Ze(p,t,e,u[e]);for(const[t,e]of f){if(!c()||p.closed)break;r[t](e)}f.length=0};a.assigned?g():a.onAssigned=g}catch(p){d(p)}})}function Qe(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,a=!1,i=null;t.on("setBar",async(o,s,l)=>{const c=t.controls?.thumbnails,{url:d,scale:p}=e.thumbnails;if(!c||!d)return;if("hover"===o||"played"===o&&l&&E){if(i||a||(a=!0,i=await j(d,p),a=!1),!i)return;const o=r.clientWidth*s;o>0&&or.clientWidth-u/2?R(a,"left",r.clientWidth-u+"px"):R(a,"left",o-u/2+"px")}(o)}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,a=!1,i=null)}})}function tr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(h(t))return;const o=function(t){const e=de.get(t);return de.delete(t),e||fe(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await At(o.scope)&&o.active()&&(t.loading.show=!0));const a=t.url,i=e.type||Z(n),s=e.customType[i];if(i&&s){if(!(await At(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;Ze(l,t,"video:canplay",()=>{c=!d}),Ze(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,i&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>ve(o,t))}else{if(a&&URL.revokeObjectURL(a),!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(a!==t.url&&(t.option.url=n,o.active()&&t.isReady&&a)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||Ze(o.scope,t,"video:canplay",e)}}catch(a){ve(o,a)}finally{me(o)}}})}class er{constructor(t){tr(t),function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:a}}=t;it(t,"play",{async value(){const i=he(t),s=await a.play();if(!i())return s;const l=e.get("Play");if(!i())return s;if(r.show=l,!i())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${et(t.currentTime)} / ${et(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}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=Q(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)}})}(t),function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=Q(n,0,t.duration))}})}(t),function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>Je(t,e,0);it(t,"switchQuality",{value:e=>Je(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})}(t),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}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(a){if(!h(t)){if(a||(a="default"),"default"===a)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=a.split(":").map(Number),r=ae({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(h(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=a}r.show=`${e.get("Aspect Ratio")}: ${"default"===a?e.get("Default"):a}`,h(t)||t.emit("aspectRatio",a)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=V("canvas");it(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(a){e.show=a,o(a)}})}),it(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(a){e.show=a,o(a)}})}),it(t,"screenshot",{value:async e=>{const n=await t.getDataURL();return J(n,`${e||`artplayer_${et(r.currentTime)}`}.png`),t.emit("screenshot",n),n}})}(t),_e(t),We(t),Ge(t),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})}(t),function(t){it(t,"played",{get:()=>t.currentTime/t.duration})}(t),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)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(h(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!oe(o))return;const a=H(e),i=ae(a,o.width/o.height);i&&!h(t)&&("width"===i.axis?(r.style.width=i.width/a.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=i.height/a.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;it(t,"rect",{get:()=>H(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})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){h(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(tt(o))}`,h(t)||t.emit("flip",o))}})}(t),function(t){it(t,"mini",Be(t))}(t),function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){R(e,"backgroundImage",`url(${t})`)}})}(t),ie(t),function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),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:a}=t.subtitle;if(!n.$track||0===a.length)return;const i=Q(o,-10,10);n.$track.offset=i;for(let e=0;e{switch(t.availability){case"available":a=!0;break;case"not-available":a=!1}}):a=!1,it(t,"airplay",{value(){a?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),Ke(t),Qe(t),be(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const i in e.moreVideoAttr)t.attr(i,e.moreVideoAttr[i]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=Q(e.volume,0,1));const a=r.get("volume");"number"===typeof a&&(n.volume=Q(a,0,1)),e.poster&&R(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const i in e.cssVar)t.cssVar(i,e.cssVar[i]);t.url=e.url}(t)}}const rr=new WeakMap,nr="art-auto-orientation-fullscreen";function or(t){if(rr.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const ar="art-auto-orientation",ir=["width","height","transform-origin","transform"];function sr(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 oe(t)&&oe(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=u(t);let o,a=()=>{};function i(){a(),a=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:a}of e)r.style.setProperty(t,o,a);const n=r.classList.contains(ar);r.classList.remove(ar),n&&(t.isRotate=!1,h(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const a=U();if(h(t)||!t.fullscreenWeb)return;const i=r.ownerDocument.documentElement;o??(o=ir.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=i.clientHeight-a.top-a.bottom+"px",r.style.height=i.clientWidth-a.left-a.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${a.top}px, -${i.clientWidth-a.right}px)`,r.classList.add(ar),t.isRotate=!0,n&&t.emit("resize")}return n.add(i),r=>{h(t)||(r?o?s(!1):e()&&(a(),a=zt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):i())}}(t,n),a=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(nr),t&&(t.cancelled=!0,or(t),t.settled&&rr.get(t.orientation)===t&&rr.delete(t.orientation))}return u(t).add(o),a=>{if(h(t))return;if(!a)return void o();if(n&&!n.cancelled&&rr.get(n.orientation)===n)return;const i=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof i?.lock||"function"!==typeof i.unlock||!e())return;const s={orientation:i,cancelled:!1,settled:!1};n=s,rr.set(i,s);const l=()=>!h(t)&&!s.cancelled&&n===s&&rr.get(i)===s,c=e=>{s.settled=!0;const o=l();rr.get(i)===s&&rr.delete(i),n===s&&(n=void 0),o&&(r.classList.remove(nr),t.notice.show=e)};try{const t=i.lock(i.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,l()?r.classList.add(nr):(or(s),rr.get(i)===s&&rr.delete(i))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",a),u(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",a)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function lr(t){const{i18n:e,icons:r,storage:n,constructor:o,proxy:a,template:{$poster:i}}=t,s=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '}),l=L(".art-auto-playback-last",s),c=L(".art-auto-playback-jump",s),d=L(".art-auto-playback-close",s);A(d,r.close);let p=null;function u(){const r=(n.get("times")||{})[t.option.id||t.option.url];clearTimeout(p),R(s,"display","none"),r&&r>=o.AUTO_PLAYBACK_MIN&&(R(s,"display","flex"),l.textContent=`${e.get("Last Seen")} ${et(r)}`,c.textContent=e.get("Jump Play"),a(d,"click",()=>{R(s,"display","none")}),a(c,"click",()=>{t.seek=r,K(t.play()),R(i,"display","none"),R(s,"display","none")}),t.once("video:timeupdate",()=>{p=setTimeout(()=>{R(s,"display","none")},o.AUTO_PLAYBACK_TIMEOUT)}))}return t.on("video:timeupdate",()=>{if(t.playing){const e=n.get("times")||{},r=Object.keys(e);r.length>o.AUTO_PLAYBACK_MAX&&delete e[r[0]],e[t.option.id||t.option.url]=t.currentTime,n.set("times",e)}}),t.on("ready",u),t.on("restart",u),{name:"auto-playback",get times(){return n.get("times")||{}},clear:()=>n.del("times"),delete(t){const e=n.get("times")||{};return delete e[t],n.set("times",e),e}}}function cr(t){const{constructor:e,proxy:r,template:{$player:n,$video:o}}=t;let a=null,i=!1,s=1;const l=()=>{clearTimeout(a),i&&(i=!1,t.playbackRate=s,M(n,"art-fast-forward"))};return r(o,"touchstart",r=>{1===r.touches.length&&t.playing&&!t.isLock&&(a=setTimeout(()=>{i=!0,s=t.playbackRate,t.playbackRate=e.FAST_FORWARD_VALUE,P(n,"art-fast-forward")},e.FAST_FORWARD_TIME))}),t.on("document:touchmove",l),t.on("document:touchend",l),{name:"fastForward",get state(){return z(n,"art-fast-forward")}}}function dr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return z(n,"art-lock")}function a(){P(n,"art-lock"),t.isLock=!0,t.emit("lock",!0)}function i(){M(n,"art-lock"),t.isLock=!1,t.emit("lock",!1)}return e.add({name:"lock",mounted(e){const n=A(e,r.lock),o=A(e,r.unlock);R(n,"display","none"),t.on("lock",t=>{t?(R(n,"display","inline-flex"),R(o,"display","none")):(R(n,"display","none"),R(o,"display","inline-flex"))})},click(){o()?i():a()}}),{name:"lock",get state(){return o()},set state(t){t?a():i()}}}function pr(t){return t.on("control",e=>{e?M(t.template.$player,"art-mini-progress-bar"):P(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){h(t.art)||!e.miniProgressBar||e.isLive||t.add(pr),!h(t.art)&&e.lock&&E&&t.add(dr),h(t.art)||!e.autoPlayback||e.isLive||t.add(lr),!h(t.art)&&e.autoOrientation&&E&&t.add(sr),!h(t.art)&&e.fastForward&&E&&!e.isLive&&t.add(cr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){G(!h(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(h(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(h(t.art))return t;let o=n;const a=lt(t,o);if(h(t.art))return t;const i=`Cannot add a plugin that already has the same name: ${n}`;return h(t.art)||(G(!a,i),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),h(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const hr=new WeakMap;function fr(t){return!t.closed&&!hr.get(t)}function mr(t){hr.set(t,(hr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(hr.get(t)||1)-1;r?hr.set(t,r):hr.delete(t)}}const gr=new WeakMap,vr=new WeakMap,yr=["$parent","$parents","$option","$events","$formatted"];function br(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=gr.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(gr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function wr(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 xr(t){const e=gr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function kr(t,e){for(let r=0;r{d&&d!==r&&d.dispose()},()=>Pr(t,o)])try{e()}catch(p){p instanceof s?c.push(...p.errors):c.push(p)}if(r.closed||h(t)||(o.push(...a.splice(0)),Sr.set(r,o),Cr.set(e,r),Lr.set(e,n)),i(),c.length)throw new s(c)},dispose(){if(l){l=!1;try{r.dispose()}finally{i()}}}}}function Or(t,e,r,n,o,a){const i=a||zr(e);if(!fr(i)||h(t))return;const s=t.proxy(r,n,e=>{if(fr(i)&&!h(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!fr(i)||h(t)?t.events.remove(s):(xr(e).events.push(s),a&&a!==Cr.get(e)&&a.add(()=>{const r=xr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Ir(t,e,r,n){const o=zr(e);if(!fr(o)||h(t))return;const a=(...e)=>{if(fr(o)&&!h(t))return n(...e)};t.on(r,a),o.add(()=>{t.off(r,a)})}function _r(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:a},template:{$player:i,$setting:s,$bottom:l}}=e;if(!n.setting||!t.show||!r)return;const c=i.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),p=c.width/i.offsetWidth||1,u=(d.left-c.left+d.width/2)/p-i.clientLeft,h=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:a,controlCenter:i,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*a),Math.max(0,r-s-c)),left:Math.max(c,Math.min(i-d/2,e-c-d))}}({containerWidth:i.clientWidth,containerHeight:i.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:a,controlCenter:u,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||E||(u+h.width/2>i.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const Nr=new WeakMap;function Dr(t){Nr.delete(t)}const Wr=new WeakMap;function Fr(t,e){e?Wr.set(t,e):Wr.delete(t)}function Vr(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=Wr.get(t),o=n?.();for(const a of["html","icon","tooltip"]){const t=e.get(a)?.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?.(),Fr(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 Yr=new WeakMap;async function Br(t,e,r,n,o,a,i,s){try{const l=zr(e),c=zr(a),d=(Yr.get(a)||0)+1;Yr.set(a,d);const p=()=>fr(l)&&fr(c)&&!h(t.art)&&Yr.get(a)===d;if(s?.(),!p())return;const u=await o.call(t.art,e,r,n);p()&&Reflect.set(a,i,u)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}}function Hr(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 jr=new WeakMap;function qr(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof s?e.push(...r.errors):e.push(r)}if(e.length)throw new s(e)}function Ur(t){jr.get(t)?.()}function Xr(t,e){const r=t.find(e.name);if(h(t.art))return r||e;if(!r)return t.add(e);Dr(r),Ur(r);const n=Vr(r),o=r.$item,a=o?.parentNode,i=o?.nextSibling,s=o?Hr(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 a=[],i=[];try{for(const e of r){const r=Rr(t.art,e);r&&a.push(r)}for(const t of n)i.push(mr(Er(t)))}catch(l){try{qr([...a.reverse().map(t=>t.resume),...i])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,qr([...a.reverse().map(t=>t.resume),...i]))},dispose(){s&&(s=!1,qr([...a.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Tr(t)),...i]))}}}(t,r);let p=!0,f=!1;const m=()=>{if(!p)return;p=!1;for(const t of d.items)jr.get(t)===m&&jr.delete(t);if(h(t.art))return void d.dispose();const e=r.$item;try{qr([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{a&&o&&a.insertBefore(o,i?.parentNode===a?i:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&_(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(u){console.warn("ArtPlayer setting restore failed:",u)}},g=()=>p&&!h(t.art)&&jr.get(r)===m;for(const u of d.items)jr.set(u,m);const v=u(t.art).add(()=>{p=!1;for(const t of d.items)jr.get(t)===m&&jr.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 a=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,a))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,g),!g())return r;if(t.format(),!g())return r;if(t.createItem(r,!0),!g())return r;if(f=!0,t.render(),!g())return r;p=!1;for(const t of d.items)jr.get(t)===m&&jr.delete(t);return d.dispose(),r}catch(y){throw g()&&m(),y}finally{v()}}const Gr=new WeakMap;function Kr(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",A(r,t)}})}function Zr(t,e,r=!1){const n=function(t){const e=jr.get(t);return()=>!e||jr.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),a=e.$item;let i="selector";lt(e,"switch")&&(i="switch"),lt(e,"range")&&(i="range"),lt(e,"onClick")&&(i="button");const{icons:s,constructor:l}=t.art;if(!n())return;const c=function(t,e,r=u(t)){const n=Cr.get(e);(!n||fr(n)||n.closed)&&Ar(t,e);const o=r.child();return Cr.set(e,o),Lr.set(e,r),Sr.set(o,xr(e).events),o.add(()=>{Pr(t,Sr.get(o))}),o}(t.art,e,Er(o)),d=()=>fr(c)&&!h(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(Fr(e),P(p,"art-setting-item"),R(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=A(p,'
'),u=A(p,'
'),f=document.createElement("div");switch(P(f,"art-setting-item-left-icon"),i){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;A(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;A(f,t)}else A(f,s.check)}if(A(n,f),!d())return;Kr(e,"icon",f);const m=document.createElement("div");P(m,"art-setting-item-left-text");const g=e.html||"";if(!d())return;A(m,g),A(n,m),Kr(e,"html",m);const v=document.createElement("div");P(v,"art-setting-item-right-tooltip");const y=e.tooltip||"";if(!d())return;switch(A(v,y),A(u,v),Kr(e,"tooltip",v),i){case"switch":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=A(t,s.switchOn),n=A(t,s.switchOff),o=e.switch;if(!d())return;R(o?n:r,"display","none"),A(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let a=e.switch;if(!d())return;Fr(e,()=>{const t=a;return()=>{a=t}}),it(e,"switch",{configurable:!0,get:()=>a,set(t){a=t,t?(R(n,"display","none"),R(r,"display",null)):(R(n,"display",null),R(r,"display","none"))}});break}case"range":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",A(t,r);for(const[o,a]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,a,String(t))}P(r,"art-setting-range"),A(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Fr(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");P(t,"art-setting-item-right-icon"),A(t,s.arrowRight),A(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,a=zr(e),i=(t,r,n)=>Or(o,e,t,r,n,a);switch(n){case"switch":e.onSwitch&&i(r,"click",n=>Br(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,a]of[["change","onRange"],["input","onChange"]])e[a]&&i(n,o,o=>Br(t,e,r,o,e[a],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":i(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return Br(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&P(r,"art-current");break;case"button":e.onClick&&i(r,"click",n=>Br(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,p,i),!d())return;it(e,"$item",{configurable:!0,get:()=>p}),r&&a?.parentNode?a.replaceWith(p):A(o,p),e.mounted&&d()&&zt(c,()=>{if(!h(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(f){try{c.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw p.remove(),f}}function Jr(t,e=t.option){if(h(t.art))return;const r=t.cache.get(e);if(r&&!fr(Er(r)))return;const n=(Gr.get(t)||0)+1;Gr.set(t,n);const o=()=>Gr.get(t)===n&&!h(t.art),a=t.active,i=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),s=()=>{t.active=a,a&&t.cache.has(a)&&_(t.cache.get(a),"art-current");for(const[e,r,n]of i)t.$parent.style.setProperty(e,r,n)};if(t.active=e,r)try{_(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!Er(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=u(t.art).child();return $r.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),a=()=>!n.closed&&!h(t.art)&&t.cache.get(e)===r,i=[];try{if(!a())return;P(r,"art-setting-panel"),A(t.$parent,r),_(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=vr.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=u(e).child(),n=(t,n)=>{if(r.closed||h(e))return;const o=(...t)=>{if(!r.closed&&!h(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=W(r,e.controls.setting),o=W(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||h(e)||t.resize()},a=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(a)});const{$player:i,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(i),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(i,{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 a(t){return 1===t?e.get("Normal"):t.toFixed(1)}function i(){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:a(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:a(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{i(),Ir(t,r,"video:ratechange",()=>i())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function a(t){return"default"===t?e.get("Default"):t}function i(){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:a(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:a(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{i(),Ir(t,r,"aspectRatio",()=>i())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function a(t){return e.get(tt(t))}function i(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:a(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:a(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{i(),Ir(t,r,"flip",()=>i())}}}(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)=>{Ir(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){kr(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&&_(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 a=vr.get(t)||{active:!0},i=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nxr(t).parent},$parents:{get:()=>xr(t).parents},$option:{get:()=>xr(t).option},$events:{get:()=>xr(t).events},$formatted:{get:()=>!0}}),gr.set(t,{parent:r,parents:n,option:o,events:i?.events||[],owner:a}),p.generated&&(t.name=e)}for(const p of i)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 kr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){_r(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&&Tr(n)}catch(a){r.push(a)}}try{Ar(t.art,e)}catch(a){a instanceof s?r.push(...a.errors):r.push(a)}}};if(o(e),r.length)throw new s(r)}(this,t)}remove(t){const e=this.find(t);G(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Dr(t),Ur(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const i of[()=>this.inactivate(e),()=>n?.remove(),()=>this.render()])try{i()}catch(a){a instanceof s?o.push(...a.errors):o.push(a)}if(o.length)throw new s(o)}update(t){return Xr(this,t)}add(t,e=this.option){if(h(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={};Nr.set(t,e);const r=()=>Nr.get(t)===e;return{current:r,finish(){r()&&Nr.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(i){if(h(this.art)||o&&!o.current())throw i;if(e[n]===t&&e.splice(n,1),!r&&a){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw i}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,a=document.createElement("div");R(a,"height",`${o}px`),P(a,"art-setting-item"),P(a,"art-setting-item-back");const i=A(a,'
'),s=document.createElement("div");P(s,"art-setting-item-left-icon"),A(s,n),A(i,s),A(i,e.$parent.html),Or(t.art,e.$parent,a,"click",()=>t.render(e.$parents),Er(r)),A(r,a)}(this,t)}createItem(t,e=!1){Zr(this,t,e)}render(t=this.option){Jr(this,t)}}class en{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 rn='.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 nn{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 on=new WeakMap;function an(t){return on.get(t)}function sn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const ln=St;class cn extends ln{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=u(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return on.set(t,n),r.add(()=>{sn(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?O(r,t):R(r,t,e)}update(){!function(t){const e=an(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:a}=t,{$subtitle:i}=a.template;if(i.innerHTML="",!t.activeCues.length)return;if(a.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 ${a.option.subtitle.escape?at(t):t}\n
`).join("")).join("");o()&&(i.innerHTML=s,a.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,a={...o.subtitle,...e,url:t},i=an(this),s=i.revision+1,l=await this.init(a);return!i.scope.closed&&i.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),l}createTrack(t,e){!function(t,e,r){const n=an(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:a}=t,{template:i}=a,s=i.$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=a.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{p.closed||i.$track!==d||a.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{p.closed||i.$track!==d||(a.notice.show=new Error("Failed to load subtitle track"))},p.closed||n.trackRevision!==o)return void p.dispose();s.remove(),i.$video.appendChild(d),i.$track=d;const l=t.textTrack,c=l?a.proxy(l,"cuechange",()=>{p.closed||i.$track!==d||t.update()}):()=>{};if(p.add(()=>{a.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&&sn(n)}}catch(h){if(u)throw h;if(p.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw i.$track=s,l&&l.insertBefore(s,c?.parentNode===l?c:null),h}}(this,t,e)}async init(t){const e=an(this),r=function(t){const e=t.request,r=new nn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:a}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Ct.subtitle),!t.url)return;let i;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||Z(e.url)){case"srt":return{vtt:e.onVttLoad(pt(r))};case"ass":return{vtt:e.onVttLoad(ht(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const l=void 0===s?t.url:i=ut(s.vtt);if(!r.active)return;a.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(s){if(!r.active)return;throw a.innerHTML="",n.show=s,s}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}})}}const dn=`\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
${a}
\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 pn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=L(e.container),G(this.$container,`No container element found by ${e.container}`)),G(B(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();G("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),G(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=d.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,d.set(e,t),o.releaseContainer=()=>{d.get(e)===t&&d.delete(e)}}(t,this.$container,Hr(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return dn}query(t){return L(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=pn.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);!function(t){G(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&&P(this.$player,"art-backdrop"),E&&P(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":P(this.$player,"art-destroy")}}const un=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class hn{on(t,e,r){const n=this.e||(this.e={});let o=un(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 a=!1;function i(...e){a||(a=!0,n.off(t,i),o.apply(r,e))}return i._=e,this.on(t,i,r)}emit(t,...e){const r=this.e||(this.e={}),n=(un(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=un(r,t)?r[t]:void 0,o=[];if(n&&e)for(let a=0,i=n.length;ae.call(this,this)),gn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${gn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=p(t);return e.rollback=void 0,!e.scope.closed})(this)&&mn.push(this)}catch(n){try{f(this,mn,!0,gn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(a){console.warn("Failed to clean up ArtPlayer initialization:",a)}throw n}}static get instances(){return mn}static get version(){return a}static get config(){return i}static get utils(){return mt}static get scheme(){return Ct}static get Emitter(){return hn}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return pn.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:x?"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){f(this,mn,t,gn.REMOVE_SRC_WHEN_DESTROY)}}return gn.STYLE=rn,gn.DEBUG=!1,gn.CONTEXTMENU=!0,gn.NOTICE_TIME=2e3,gn.SETTING_WIDTH=250,gn.SETTING_ITEM_WIDTH=200,gn.SETTING_ITEM_HEIGHT=35,gn.RESIZE_TIME=200,gn.SCROLL_TIME=200,gn.SCROLL_GAP=50,gn.AUTO_PLAYBACK_MAX=10,gn.AUTO_PLAYBACK_MIN=5,gn.AUTO_PLAYBACK_TIMEOUT=3e3,gn.RECONNECT_TIME_MAX=5,gn.RECONNECT_SLEEP_TIME=1e3,gn.CONTROL_HIDE_TIME=3e3,gn.DBCLICK_TIME=300,gn.DBCLICK_FULLSCREEN=!0,gn.MOBILE_DBCLICK_PLAY=!0,gn.MOBILE_CLICK_PLAY=!1,gn.AUTO_ORIENTATION_TIME=200,gn.INFO_LOOP_TIME=1e3,gn.FAST_FORWARD_VALUE=3,gn.FAST_FORWARD_TIME=1e3,gn.TOUCH_MOVE_RATIO=.5,gn.VOLUME_STEP=.1,gn.SEEK_STEP=5,gn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],gn.ASPECT_RATIO=["default","4:3","16:9"],gn.FLIP=["normal","horizontal","vertical"],gn.FULLSCREEN_WEB_IN_BODY=!0,gn.LOG_VERSION=!0,gn.USE_RAF=!1,gn.REMOVE_SRC_WHEN_DESTROY=!0,T&&(window.Artplayer=gn,C("artplayer-style",rn),setTimeout(()=>{gn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${gn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),gn}); +!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{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new l,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 s?t.push(...e.errors):t.push(e)}if(t.length)throw new s(t)}}const c=new WeakMap,d=new WeakMap;function p(t){const e=c.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function u(t){return p(t).scope}function h(t){const e=p(t);return e.destroying||e.scope.closed}function f(t,e,r,n,o=!1){const i=p(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],l=t=>{try{t()}catch(e){a.push(...e instanceof s?e.errors:[e])}};n&&t.template?.$video&&l(()=>t.reset()),l(()=>i.scope.dispose()),l(()=>t.template?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),l(()=>t.emit("destroy")),o&&i.rollback&&l(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const s of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",s);if(a.length)throw a[0]}const m=new WeakMap;function g(t,e){const r=u(t).child();return m.set(e,r),r}function v(t){const e=m.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function y(t){m.get(t)?.dispose()}function b(t,e){return{on:(r,n)=>{!function(t,e,r,n){const o=v(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=v(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)}}const w=globalThis?.CUSTOM_USER_AGENT??("undefined"!==typeof navigator?navigator.userAgent:""),x=/^(?:(?!chrome|android).)*safari/i.test(w),k=/iPad|iPhone|iPod/i.test(w)&&!window.MSStream,$=k||w.includes("Macintosh")&&navigator.maxTouchPoints>=1,E=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(w)||$,T="undefined"!==typeof window&&"undefined"!==typeof document;function C(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function L(t,e=document){return e.querySelector(t)}function S(t,e=document){return Array.from(e.querySelectorAll(t))}function P(t,e){return t.classList.add(e)}function M(t,e){return t.classList.remove(e)}function z(t,e){return t.classList.contains(e)}function A(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function R(t,e,r){return t.style[e]=r,t}function O(t,e){for(const r in e)R(t,r,e[r]);return t}function I(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function _(t,e){I(t).forEach(t=>M(t,e)),P(t,e)}function N(t,e,r="top"){E||(t.setAttribute("aria-label",e),P(t,"hint--rounded"),P(t,`hint--${r}`))}function D(t,e){return j(t).includes(e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function W(t){return document.createElement(t)}function V(t="",e=""){const r=W("i");return P(r,"art-icon"),P(r,`art-icon-${t}`),A(r,e),r}function Y(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function B(t){return t.getBoundingClientRect()}function H(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function j(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function q(){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;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}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:P,append:A,assToVtt:ut,capitalize:Q,clamp:J,createElement:W,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:j,getExt:K,getIcon:V,getRect:B,getSafeAreaInsets:q,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:z,includeFromEvent:D,inverseClass:_,isBrowser:T,isIOS:k,isIOS13:$,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:E,isSafari:x,loadImg:H,mergeDeep:ct,query:L,queryAll:S,remove:function(t){return t.parentNode.removeChild(t)},removeClass:M,replaceElement:F,secondToTime:tt,setStyle:R,setStyleText:C,setStyles:O,siblings:I,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:Y,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:N,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:w,vttToBlob:pt},Symbol.toStringTag,{value:"Module"}));function ft(t,e){return A(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 z(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?P(e,r):M(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t;if(h(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=g(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){P(t,`art-${r}`),P(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):A(e,t),i.html&&A(t,i.html),i.style&&O(t,i.style),i.tooltip&&N(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{y(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{y(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,g(t,this.$parent),E||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=b(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}=b(e,t),n=L('[data-value="1"]',t);n&&_(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&_(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}=b(e,t),n=L('[data-value="default"]',t);n&&_(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(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}=b(e,t),n=L('[data-value="normal"]',t);n&&_(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(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}=B(e),{height:c,width:d}=B(r);let p=n-s,u=o-l;n+d>s+a&&(p=a-d),o+c>l+i&&(u=i-c),O(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{D(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)})})}function zt(t,e){const{$progress:r}=t.template,{left:n}=B(r),o=J((E?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 At(t,e,r=()=>!0){if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=zt(t,e);t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Rt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=v(e),{on:a}=b(t,e);let s=()=>{};const l=mt(".art-progress-hover",e),c=mt(".art-progress-loaded",e),d=mt(".art-progress-played",e),p=mt(".art-progress-highlight",e),u=mt(".art-progress-indicator",e),h=mt(".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?R(h,"left",0):o>e.clientWidth-a/2?R(h,"left",e.clientWidth-a+"px"):R(h,"left",o-a/2+"px")}r.indicator?A(u,r.indicator):R(u,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&E;if("loaded"===r&&R(c,"width",100*n+"%"),"hover"===r&&(R(l,"width",100*n+"%"),D(a,p)?function(r){const{width:n}=zt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const i=h.clientWidth;n<=i/2?R(h,"left",0):n>e.clientWidth-i/2?R(h,"left",e.clientWidth-i+"px"):R(h,"left",n-i/2+"px")}(a):f(a),0===n?M(o,"art-progress-hover"):P(o,"art-progress-hover")),"played"===r&&(R(d,"width",100*n+"%"),R(u,"left",100*n+"%")),m){P(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=Pt(i,()=>{M(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 Ot(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Rt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=b(t,e);if(!E){let e=!1;i(r,"click",e=>{e.target!==n&&At(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=zt(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=zt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function It(t){const{option:e}=t.art;e.isLive||t.add(Ot({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}=b(e,t),{icons:o,i18n:i}=e,a=ft(t,o.play),s=ft(t,o.pause);function l(){R(a,"display","flex"),R(s,"display","none")}function c(){R(a,"display","none"),R(s,"display","flex")}N(a,i.get("Play")),N(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}=b(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,'
'),p=ft(d,'
'),u=ft(p,'
'),h=ft(d,'
');function f(t){const{top:e,height:r}=B(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)R(i,"display","none"),R(a,"display","flex"),R(h,"top","100%"),R(u,"top","100%"),c.textContent="0";else{const t=100*e.volume;R(i,"display","flex"),R(a,"display","none"),R(h,"top",100-t+"%"),R(u,"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}),E)R(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=>({...t,style:E?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=b(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&&!u(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!E&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=b(e,t),{icons:n}=e;ft(t,n.screenshot),r(t,"click",()=>{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}=b(e,t),{icons:o,i18n:i}=e;ft(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{N(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}=b(e,t),{icons:o,i18n:i}=e;ft(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{N(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}=b(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}=b(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenWebOn),s=ft(t,o.fullscreenWebOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(N(t,i.get("Exit Web Fullscreen")),R(a,"display","none"),R(s,"display","inline-flex")):(N(t,i.get("Web Fullscreen")),R(a,"display","inline-flex"),R(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}=b(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenOn),s=ft(t,o.fullscreenOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(N(t,i.get("Exit Fullscreen")),R(a,"display","none"),R(s,"display","inline-flex")):(N(t,i.get("Fullscreen")),R(a,"display","inline-flex"),R(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rNt.get(t).option.selector}),it(t,"$control_item",{get:()=>Nt.get(t).item}),it(t,"$control_value",{get:()=>Nt.get(t).value})),Nt.set(t,e)}function Ft(t,e){t.innerHTML=e}function Wt(t,e,r,n,o){const{proxy:i}=t.events,a=v(n),s=r.selector;P(n,"art-control-selector");const l=document.createElement("div");P(l,"art-selector-value"),A(l,r.html),n.textContent="",A(n,l);const c=ft(n,'
');for(let u=0;u{if(a.closed)return;const o=j(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 _t.set(t,e),()=>{_t.get(t)===e&&_t.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()&&Ft(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Vt 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;g(t,n);const{on:o}=b(t,n);o("mousemove",()=>{E||(this.show=!0)}),o("click",()=>{E?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=D(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?(M(r,"art-hide-cursor"),P(r,"art-hover"),this.timer=Date.now()):(P(r,"art-hide-cursor"),M(r,"art-hover"))}),this.init(),u(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=v(e),{on:i}=b(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(){It(this)}add(t){if(h(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){Ft(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Yt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(h(t))return;const n=D(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),u(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(h(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),h(t))return;(!E||!t.isLock&&i)&&G(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),h(t))return;E?!t.isLock&&s&&G(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}const Bt=new WeakMap,Ht=new WeakMap,jt=new WeakMap;function qt(t){return jt.get(t)||u(t)}function Ut(t){const e=Bt.get(t),r=jt.get(t);return()=>Bt.get(t)===e&&(!e||e.active())&&jt.get(t)===r&&(!r||!r.closed)}function Xt(t){const e=jt.get(t),r=u(t).child(),n=r.child();jt.set(t,r),r.add(()=>{jt.get(t)===r&&jt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!h(t)&&!n.closed&&Bt.get(t)===o};return Bt.set(t,o),n.add(()=>{Bt.get(t)===o&&Bt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function Gt(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function Kt(t,e,r){Ht.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Ht.get(t)===e&&(Ht.delete(t),Gt(e))}}function Zt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Jt(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!h(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),u(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(h(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:Ut(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{At(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(h(t))return;const n=(...e)=>{if(!h(t))return r(...e)};t.on(e,n),u(t).add(()=>{t.off(e,n)})}}function ie(t){if(!t.constructor.USE_RAF)return;const e=u(t);let r=()=>{};const n=()=>{h(t)||(t.playing&&t.emit("raf"),h(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:u(e),cleaning:!1})}(this,t),u(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Yt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{h(t)||(P(r,"art-hover"),t.emit("hover",!0,e))},e=>{h(t)||(M(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{h(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(),h(t)||(t.aspectRatio=e,h(t)||(n.show=""))});const i=u(t);let a=()=>{};const s=()=>{h(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(!E||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=u(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)),h(t)||(s=!0,Pt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;u(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(h(t))return;const a=++n,s={disposers:[]},l=()=>a!==n||h(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||h(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}),E||this.init()}init(){const t=this.art;if(h(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(!h(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:()=>V(r,e[r])})}}class me extends Ct{constructor(t){super(t),this.name="info",E||this.init()}init(){const{proxy:t,constructor:e,template:{$infoPanel:r,$infoClose:n,$video:o}}=this.art;t(n,"click",()=>{this.show=!1});let i=()=>{};const a=S("[data-video]",r)||[];this.art.on("destroy",()=>i());const s=u(this.art);!function t(){for(let e=0;e{R(o,"display","none"),R(i,"display",null)}),n.proxy(e.$state,"click",()=>G(t.play()))}}class be{constructor(t){this.art=t,this.timer=null,u(t).add(()=>this.destroy()),t.on("destroy",()=>this.destroy())}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}set show(t){if(u(this.art).closed)return;const{constructor:e,template:{$player:r,$noticeInner:n}}=this.art;t?(n.textContent=t instanceof Error?t.message.trim():t,P(r,"art-notice-show"),clearTimeout(this.timer),this.timer=setTimeout(()=>{n.textContent="",M(r,"art-notice-show")},e.NOTICE_TIME)):M(r,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function we({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function xe(t,e){if(!we(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 we(r)?r:void 0}function ke(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(h(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!we(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||h(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function $e(t,e,r,n=!1){const o=e=>{h(t)||r(e)};t[n?"once":"on"](e,o),u(t).add(()=>{t.off(e,o)})}function Ee(t,e,r){for(const[n,o]of e){if(h(t)||r&&!r())return;t[n].show=o}}function Te(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=qt(t),l=0;return{reset(){l=0,a?.dispose(),M(i,"art-error")},loadStart(){M(i,"art-error")},schedule(c){(async c=>{if(h(t))return;const d=qt(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=()=>!h(t)&&!p.closed&&d===qt(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Ce(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{h(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Te(t);!function(t,e){$e(t,"video:canplay",()=>{e.reset(),Ee(t,[["loading",!1]])}),$e(t,"video:canplay",()=>{Ee(t,[["loading",!1],["controls",!0],["mask",!0]]),h(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;$e(t,"video:ended",()=>{if(e.loop){const e=Ut(t);if(t.seek=0,h(t)||!e())return;G(t.play()),e()&&Ee(t,[["controls",!1],["mask",!1]],e)}else Ee(t,[["controls",!0],["mask",!0]])})}(t),$e(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;$e(t,"video:loadedmetadata",()=>{t.emit("resize"),E&&Ee(t,[["loading",!1],["controls",!0],["mask",!0]])}),$e(t,"video:loadstart",()=>{e.loadStart(),Ee(t,[["loading",!0],["mask",!1],["controls",!0]])}),$e(t,"video:pause",()=>{Ee(t,[["controls",!0],["mask",!0]])}),$e(t,"video:play",()=>{Ee(t,[["mask",!1]]),h(t)||R(r,"display","none")}),$e(t,"video:playing",()=>Ee(t,[["mask",!1]])),$e(t,"video:progress",()=>{t.playing&&Ee(t,[["loading",!1]])}),$e(t,"video:seeked",()=>Ee(t,[["loading",!1],["mask",!0]])),$e(t,"video:seeking",()=>Ee(t,[["loading",!0],["mask",!1]])),$e(t,"video:timeupdate",()=>Ee(t,[["mask",!1]])),$e(t,"video:waiting",()=>Ee(t,[["loading",!0],["mask",!1]]))}(t,e)}const Le=[["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"]],Se=(()=>{if("undefined"===typeof document)return!1;const t=Le[0],e={};for(const r of Le){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Pe={change:Se.fullscreenchange,error:Se.fullscreenerror},Me={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Me.off("change",o),r()};Me.on("change",o);const i=t[Se.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Me.isFullscreen)return void t();const r=()=>{Me.off("change",r),t()};Me.on("change",r);const n=document[Se.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Me.isFullscreen?Me.exit():Me.request(t,e),onchange(t){Me.on("change",t)},onerror(t){Me.on("error",t)},on(t,e){const r=Pe[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Pe[t];r&&document.removeEventListener(r,e,!1)},raw:Se};function ze(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(Me,{isFullscreen:{get:()=>Boolean(document[Se.fullscreenElement])},element:{enumerable:!0,get:()=>document[Se.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Se.fullscreenEnabled])}});const Ae=new WeakMap;function Re(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function Oe(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ae.get(t);if(!n){n=new WeakMap,Ae.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Re(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Re(i))}function Ie(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&&Oe(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){Ae.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&&Oe(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 _e(t,e){const r=u(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,f=!1;function m(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),m()}),St(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return Ae.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void m();if(r===s||h(t))return;s=r;const o=l,a=()=>h(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&&(f||void 0!==a||i()))&&!h(t)&&t.emit("fullscreenError",r)}),{get:()=>!h(t)&&i(),set(n){if(h(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();f=!0,d=c;const s=Ie(e,r,c,()=>{!h(t)&&c||m()},()=>!i());f=!1,l===o?a=s:s.cancel();const u=s.promise.catch(e=>{throw h(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return u.catch(()=>{}),u}}}const Ne=new WeakSet;function De(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Fe(t){Ne.delete(t),t.removeEventListener("webkitbeginfullscreen",We),t.removeEventListener("webkitpresentationmodechanged",We)}function We(t){if(Ne.has(this)&&De(this,"webkitbeginfullscreen"===t.type)){Fe(this);try{this.webkitExitFullscreen?.()}catch{}}}function Ve(t){Ne.add(t),t.addEventListener("webkitbeginfullscreen",We),t.addEventListener("webkitpresentationmodechanged",We)}function Ye(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=De(e),i=o,a=!1,s=0;const l=()=>De(e,n);function c(r){if(h(t)||(c=e,Ne.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=()=>h(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&&Ve(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:()=>!h(t)&&l(),set(r){if(h(t))return;const n=++s;if(i=Boolean(r),r){if(Fe(e),t.state="fullscreen",h(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,Ve(e)),l()&&e.webkitExitFullscreen()}}}function Be(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(h(t))return;const i=function(t){const e=Me.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:()=>ze(t,e.requestFullscreen,void 0),exit:()=>ze(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",_e(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",Ye(t)):it(t,"fullscreen",{get:()=>!1,set(){h(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",lt(t,"fullscreen"))};t.once("video:loadedmetadata",i),u(t).add(()=>{t.off("video:loadedmetadata",i)})}function He(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function je({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 qe(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()&&(je(t.placement),r()))}return u(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 s([i,a])}throw i}}),i=>{if(h(t))return;const a=++n,s=()=>a===n&&!h(t);if(i){r||(r={placement:He(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 Ue(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 Xe(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Ge(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=Ue(i.left,i.top,Xe(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 Ke(t){const{$player:e,$video:r}=t.template,n=u(t).child();let o,i,a=0,s=!1,l=!1;const c=()=>!h(t)&&e.classList.contains("art-mini");function d(){if(i){const e=i,r=a;i=void 0;try{je(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(h(t))return;const r=++a;l=!1,d(),h(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(h(t))return;const u=++a;if(s)l=!0;else if(t.state="mini",!h(t)&&u===a){i??(i=He(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Ge(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void f();if(!o||h(t))return;if(u!==a)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),h(t)||u!==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}:{...Ue(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,Xe(o.element));if(h(t)||u!==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),h(t)||u!==a)return;t.storage.set("left",i.left)}h(t)||u!==a||t.emit("mini",!0)}catch(m){const r=l;throw l=!1,h(t)||u!==a&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),m}}}return n.add(()=>{a++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?f():p()}}}const Ze=new WeakSet,Je=t=>"picture-in-picture"===t.webkitPresentationMode;function Qe(t){Ze.delete(t),t.removeEventListener("webkitpresentationmodechanged",tr),t.removeEventListener("enterpictureinpicture",tr)}function tr(){if(Ze.has(this)&&Je(this)){Qe(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function er(t){Ze.add(t),t.addEventListener("webkitpresentationmodechanged",tr),t.addEventListener("enterpictureinpicture",tr)}function rr(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=u(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||!h(t)&&a||d()},e=>{h(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",!h(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),St(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!h(t)&&o()?e:null,set(n){if(h(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",h(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=u(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(h(t)||Ze.has(e))return;const s=Je(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),h(t)||i!==l||Je(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&er(e),Je(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])St(r,e,l,()=>s());return{get:()=>!h(t)&&Je(e),set(r){if(h(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(Qe(e),t.state="pip",h(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===i&&(o=!1),c}}else o&&(o=!1,er(e)),Je(e)&&e.webkitSetPresentationMode("inline");h(t)||n!==i||l!==a||Je(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){h(t)||(r.show=e.get("PIP Not Supported"))}})}function nr(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&&_t.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!h(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!h(t)&&a()&&(n.show=r)}return e.html}})}})}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(h(t)||e===t.url)return void n();const i=Xt(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(),u={"video:error":d,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){d(e)}},"video:canplay":()=>{if(!c())return;p.dispose();(async()=>{if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}})().catch(d)}},h=a.child(),f=[],m=Object.keys(u);for(const e of m)or(h,t,e,t=>{i.acceptingEvents&&f.push([e,t])},!1);if(Kt(t,i,e),!c())return;if(t.notice.show="",!c())return;const g=()=>{if(h.dispose(),!e)return void l();const r={};for(const e of m)r[e]=or(p,t,e,u[e]);for(const[t,e]of f){if(!c()||p.closed)break;r[t](e)}f.length=0};i.assigned?g():i.onAssigned=g}catch(p){d(p)}})}function ar(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",async(o,s,l)=>{const c=t.controls?.thumbnails,{url:d,scale:p}=e.thumbnails;if(!c||!d)return;if("hover"===o||"played"===o&&l&&E){if(a||i||(i=!0,a=await H(d,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-u/2?R(i,"left",r.clientWidth-u+"px"):R(i,"left",o-u/2+"px")}(o)}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function sr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(h(t))return;const o=function(t){const e=Ht.get(t);return Ht.delete(t),e||Xt(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=>Zt(o,t))}else{if(i&&URL.revokeObjectURL(i),!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){Zt(o,i)}finally{Gt(o)}}})}class lr{constructor(t){sr(t),function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=Ut(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()})}(t),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}})}(t),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)}})}(t),function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=J(n,0,t.duration))}})}(t),function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),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})}(t),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}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!h(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=xe({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(h(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}`,h(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=W("canvas");it(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),it(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),it(t,"screenshot",{value:async e=>{const n=await t.getDataURL();return Z(n,`${e||`artplayer_${tt(r.currentTime)}`}.png`),t.emit("screenshot",n),n}})}(t),Be(t),qe(t),rr(t),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})}(t),function(t){it(t,"played",{get:()=>t.currentTime/t.duration})}(t),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)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(h(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!we(o))return;const i=B(e),a=xe(i,o.width/o.height);a&&!h(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}))}})}(t),function(t){const e=t;it(t,"rect",{get:()=>B(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})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){h(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,h(t)||t.emit("flip",o))}})}(t),function(t){it(t,"mini",Ke(t))}(t),function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){R(e,"backgroundImage",`url(${t})`)}})}(t),ke(t),function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),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{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,it(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),nr(t),ar(t),Ce(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=J(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=J(i,0,1)),e.poster&&R(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const cr=new WeakMap,dr="art-auto-orientation-fullscreen";function pr(t){if(cr.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const ur="art-auto-orientation",hr=["width","height","transform-origin","transform"];function fr(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 we(t)&&we(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=u(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,h(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=q();if(h(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=hr.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=>{h(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(dr),t&&(t.cancelled=!0,pr(t),t.settled&&cr.get(t.orientation)===t&&cr.delete(t.orientation))}return u(t).add(o),i=>{if(h(t))return;if(!i)return void o();if(n&&!n.cancelled&&cr.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,cr.set(a,s);const l=()=>!h(t)&&!s.cancelled&&n===s&&cr.get(a)===s,c=e=>{s.settled=!0;const o=l();cr.get(a)===s&&cr.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,l()?r.classList.add(dr):(pr(s),cr.get(a)===s&&cr.delete(a))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),u(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function mr(t){const{i18n:e,icons:r,storage:n,constructor:o,proxy:i,template:{$poster:a}}=t,s=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '}),l=L(".art-auto-playback-last",s),c=L(".art-auto-playback-jump",s),d=L(".art-auto-playback-close",s);A(d,r.close);let p=null;function u(){const r=(n.get("times")||{})[t.option.id||t.option.url];clearTimeout(p),R(s,"display","none"),r&&r>=o.AUTO_PLAYBACK_MIN&&(R(s,"display","flex"),l.textContent=`${e.get("Last Seen")} ${tt(r)}`,c.textContent=e.get("Jump Play"),i(d,"click",()=>{R(s,"display","none")}),i(c,"click",()=>{t.seek=r,G(t.play()),R(a,"display","none"),R(s,"display","none")}),t.once("video:timeupdate",()=>{p=setTimeout(()=>{R(s,"display","none")},o.AUTO_PLAYBACK_TIMEOUT)}))}return t.on("video:timeupdate",()=>{if(t.playing){const e=n.get("times")||{},r=Object.keys(e);r.length>o.AUTO_PLAYBACK_MAX&&delete e[r[0]],e[t.option.id||t.option.url]=t.currentTime,n.set("times",e)}}),t.on("ready",u),t.on("restart",u),{name:"auto-playback",get times(){return n.get("times")||{}},clear:()=>n.del("times"),delete(t){const e=n.get("times")||{};return delete e[t],n.set("times",e),e}}}function gr(t){const{constructor:e,proxy:r,template:{$player:n,$video:o}}=t;let i=null,a=!1,s=1;const l=()=>{clearTimeout(i),a&&(a=!1,t.playbackRate=s,M(n,"art-fast-forward"))};return r(o,"touchstart",r=>{1===r.touches.length&&t.playing&&!t.isLock&&(i=setTimeout(()=>{a=!0,s=t.playbackRate,t.playbackRate=e.FAST_FORWARD_VALUE,P(n,"art-fast-forward")},e.FAST_FORWARD_TIME))}),t.on("document:touchmove",l),t.on("document:touchend",l),{name:"fastForward",get state(){return z(n,"art-fast-forward")}}}function vr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return z(n,"art-lock")}function i(){P(n,"art-lock"),t.isLock=!0,t.emit("lock",!0)}function a(){M(n,"art-lock"),t.isLock=!1,t.emit("lock",!1)}return e.add({name:"lock",mounted(e){const n=A(e,r.lock),o=A(e,r.unlock);R(n,"display","none"),t.on("lock",t=>{t?(R(n,"display","inline-flex"),R(o,"display","none")):(R(n,"display","none"),R(o,"display","inline-flex"))})},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function yr(t){return t.on("control",e=>{e?M(t.template.$player,"art-mini-progress-bar"):P(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class br{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){h(t.art)||!e.miniProgressBar||e.isLive||t.add(yr),!h(t.art)&&e.lock&&E&&t.add(vr),h(t.art)||!e.autoPlayback||e.isLive||t.add(mr),!h(t.art)&&e.autoOrientation&&E&&t.add(fr),!h(t.art)&&e.fastForward&&E&&!e.isLive&&t.add(gr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!h(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(h(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(h(t.art))return t;let o=n;const i=st(t,o);if(h(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return h(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),h(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const wr=new WeakMap;function xr(t){return!t.closed&&!wr.get(t)}function kr(t){wr.set(t,(wr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(wr.get(t)||1)-1;r?wr.set(t,r):wr.delete(t)}}const $r=new WeakMap,Er=new WeakMap,Tr=["$parent","$parents","$option","$events","$formatted"];function Cr(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=$r.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($r.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function Lr(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 Sr(t){const e=$r.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Pr(t,e){for(let r=0;r{d&&d!==r&&d.dispose()},()=>_r(t,o)])try{e()}catch(p){p instanceof s?c.push(...p.errors):c.push(p)}if(r.closed||h(t)||(o.push(...i.splice(0)),Ir.set(r,o),Rr.set(e,r),Or.set(e,n)),a(),c.length)throw new s(c)},dispose(){if(l){l=!1;try{r.dispose()}finally{a()}}}}}function Vr(t,e,r,n,o,i){const a=i||Dr(e);if(!xr(a)||h(t))return;const s=t.proxy(r,n,e=>{if(xr(a)&&!h(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!xr(a)||h(t)?t.events.remove(s):(Sr(e).events.push(s),i&&i!==Rr.get(e)&&i.add(()=>{const r=Sr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Yr(t,e,r,n){const o=Dr(e);if(!xr(o)||h(t))return;const i=(...e)=>{if(xr(o)&&!h(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Br(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(),p=c.width/a.offsetWidth||1,u=(d.left-c.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: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:u,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||E||(u+h.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const Hr=new WeakMap;function jr(t){Hr.delete(t)}const qr=new WeakMap;function Ur(t,e){e?qr.set(t,e):qr.delete(t)}function Xr(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=qr.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?.(),Ur(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 Gr=new WeakMap;async function Kr(t,e,r,n,o,i,a,s){try{const l=Dr(e),c=Dr(i),d=(Gr.get(i)||0)+1;Gr.set(i,d);const p=()=>xr(l)&&xr(c)&&!h(t.art)&&Gr.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 Zr(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 Jr=new WeakMap;function Qr(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof s?e.push(...r.errors):e.push(r)}if(e.length)throw new s(e)}function tn(t){Jr.get(t)?.()}function en(t,e){const r=t.find(e.name);if(h(t.art))return r||e;if(!r)return t.add(e);jr(r),tn(r);const n=Xr(r),o=r.$item,i=o?.parentNode,a=o?.nextSibling,s=o?Zr(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=Wr(t.art,e);r&&i.push(r)}for(const t of n)a.push(kr(zr(t)))}catch(l){try{Qr([...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,Qr([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,Qr([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Ar(t)),...a]))}}}(t,r);let p=!0,f=!1;const m=()=>{if(!p)return;p=!1;for(const t of d.items)Jr.get(t)===m&&Jr.delete(t);if(h(t.art))return void d.dispose();const e=r.$item;try{Qr([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{i&&o&&i.insertBefore(o,a?.parentNode===i?a:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&_(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(u){console.warn("ArtPlayer setting restore failed:",u)}},g=()=>p&&!h(t.art)&&Jr.get(r)===m;for(const u of d.items)Jr.set(u,m);const v=u(t.art).add(()=>{p=!1;for(const t of d.items)Jr.get(t)===m&&Jr.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,g),!g())return r;if(t.format(),!g())return r;if(t.createItem(r,!0),!g())return r;if(f=!0,t.render(),!g())return r;p=!1;for(const t of d.items)Jr.get(t)===m&&Jr.delete(t);return d.dispose(),r}catch(y){throw g()&&m(),y}finally{v()}}const rn=new WeakMap;function nn(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",A(r,t)}})}function on(t,e,r=!1){const n=function(t){const e=Jr.get(t);return()=>!e||Jr.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=u(t)){const n=Rr.get(e);(!n||xr(n)||n.closed)&&Fr(t,e);const o=r.child();return Rr.set(e,o),Or.set(e,r),Ir.set(o,Sr(e).events),o.add(()=>{_r(t,Ir.get(o))}),o}(t.art,e,zr(o)),d=()=>xr(c)&&!h(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(Ur(e),P(p,"art-setting-item"),R(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=A(p,'
'),u=A(p,'
'),f=document.createElement("div");switch(P(f,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;A(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;A(f,t)}else A(f,s.check)}if(A(n,f),!d())return;nn(e,"icon",f);const m=document.createElement("div");P(m,"art-setting-item-left-text");const g=e.html||"";if(!d())return;A(m,g),A(n,m),nn(e,"html",m);const v=document.createElement("div");P(v,"art-setting-item-right-tooltip");const y=e.tooltip||"";if(!d())return;switch(A(v,y),A(u,v),nn(e,"tooltip",v),a){case"switch":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=A(t,s.switchOn),n=A(t,s.switchOff),o=e.switch;if(!d())return;R(o?n:r,"display","none"),A(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;Ur(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(R(n,"display","none"),R(r,"display",null)):(R(n,"display",null),R(r,"display","none"))}});break}case"range":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",A(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))}P(r,"art-setting-range"),A(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Ur(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");P(t,"art-setting-item-right-icon"),A(t,s.arrowRight),A(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=Dr(e),a=(t,r,n)=>Vr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>Kr(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=>Kr(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 Kr(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&P(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>Kr(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):A(o,p),e.mounted&&d()&&Pt(c,()=>{if(!h(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(f){try{c.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw p.remove(),f}}function an(t,e=t.option){if(h(t.art))return;const r=t.cache.get(e);if(r&&!xr(zr(r)))return;const n=(rn.get(t)||0)+1;rn.set(t,n);const o=()=>rn.get(t)===n&&!h(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)&&_(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{_(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!zr(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=u(t.art).child();return Mr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),i=()=>!n.closed&&!h(t.art)&&t.cache.get(e)===r,a=[];try{if(!i())return;P(r,"art-setting-panel"),A(t.$parent,r),_(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Er.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=u(e).child(),n=(t,n)=>{if(r.closed||h(e))return;const o=(...t)=>{if(!r.closed&&!h(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=D(r,e.controls.setting),o=D(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||h(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(),Yr(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(),Yr(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(),Yr(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)=>{Yr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Pr(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&&_(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=Er.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nSr(t).parent},$parents:{get:()=>Sr(t).parents},$option:{get:()=>Sr(t).option},$events:{get:()=>Sr(t).events},$formatted:{get:()=>!0}}),$r.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 Pr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){Br(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&&Ar(n)}catch(i){r.push(i)}}try{Fr(t.art,e)}catch(i){i instanceof s?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new s(r)}(this,t)}remove(t){const e=this.find(t);X(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{jr(t),tn(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 s?o.push(...i.errors):o.push(i)}if(o.length)throw new s(o)}update(t){return en(this,t)}add(t,e=this.option){if(h(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={};Hr.set(t,e);const r=()=>Hr.get(t)===e;return{current:r,finish(){r()&&Hr.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(h(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");R(i,"height",`${o}px`),P(i,"art-setting-item"),P(i,"art-setting-item-back");const a=A(i,'
'),s=document.createElement("div");P(s,"art-setting-item-left-icon"),A(s,n),A(a,s),A(a,e.$parent.html),Vr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),zr(r)),A(r,i)}(this,t)}createItem(t,e=!1){on(this,t,e)}render(t=this.option){an(this,t)}}class cn{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 dn='.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 pn{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 un=new WeakMap;function hn(t){return un.get(t)}function fn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const mn=Ct;class gn extends mn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=u(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return un.set(t,n),r.add(()=>{fn(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?O(r,t):R(r,t,e)}update(){!function(t){const e=hn(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=hn(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=hn(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&&fn(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=hn(this),r=function(t){const e=t.request,r=new pn(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 vn=`\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 yn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=L(e.container),X(this.$container,`No container element found by ${e.container}`)),X(Y(),"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=d.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,d.set(e,t),o.releaseContainer=()=>{d.get(e)===t&&d.delete(e)}}(t,this.$container,Zr(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return vn}query(t){return L(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=yn.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);!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&&P(this.$player,"art-backdrop"),E&&P(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":P(this.$player,"art-destroy")}}const bn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class wn{on(t,e,r){const n=this.e||(this.e={});let o=bn(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=(bn(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=bn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;ie.call(this,this)),$n.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${$n.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=p(t);return e.rollback=void 0,!e.scope.closed})(this)&&kn.push(this)}catch(n){try{f(this,kn,!0,$n.REMOVE_SRC_WHEN_DESTROY,!0)}catch(i){console.warn("Failed to clean up ArtPlayer initialization:",i)}throw n}}static get instances(){return kn}static get version(){return i}static get config(){return a}static get utils(){return ht}static get scheme(){return Et}static get Emitter(){return wn}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return yn.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:x?"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){f(this,kn,t,$n.REMOVE_SRC_WHEN_DESTROY)}}return $n.STYLE=dn,$n.DEBUG=!1,$n.CONTEXTMENU=!0,$n.NOTICE_TIME=2e3,$n.SETTING_WIDTH=250,$n.SETTING_ITEM_WIDTH=200,$n.SETTING_ITEM_HEIGHT=35,$n.RESIZE_TIME=200,$n.SCROLL_TIME=200,$n.SCROLL_GAP=50,$n.AUTO_PLAYBACK_MAX=10,$n.AUTO_PLAYBACK_MIN=5,$n.AUTO_PLAYBACK_TIMEOUT=3e3,$n.RECONNECT_TIME_MAX=5,$n.RECONNECT_SLEEP_TIME=1e3,$n.CONTROL_HIDE_TIME=3e3,$n.DBCLICK_TIME=300,$n.DBCLICK_FULLSCREEN=!0,$n.MOBILE_DBCLICK_PLAY=!0,$n.MOBILE_CLICK_PLAY=!1,$n.AUTO_ORIENTATION_TIME=200,$n.INFO_LOOP_TIME=1e3,$n.FAST_FORWARD_VALUE=3,$n.FAST_FORWARD_TIME=1e3,$n.TOUCH_MOVE_RATIO=.5,$n.VOLUME_STEP=.1,$n.SEEK_STEP=5,$n.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],$n.ASPECT_RATIO=["default","4:3","16:9"],$n.FLIP=["normal","horizontal","vertical"],$n.FULLSCREEN_WEB_IN_BODY=!0,$n.LOG_VERSION=!0,$n.USE_RAF=!1,$n.REMOVE_SRC_WHEN_DESTROY=!0,T&&(window.Artplayer=$n,C("artplayer-style",dn),setTimeout(()=>{$n.LOG_VERSION&&console.log(`%c ArtPlayer %c ${$n.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),$n}); diff --git a/packages/artplayer/dist/artplayer.legacy.js b/packages/artplayer/dist/artplayer.legacy.js index 619727b35..c7316f5ae 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,e=Object.defineProperty,r=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,l=(t,e)=>{for(var r in e||(e={}))i.call(e,r)&&s(t,r,e[r]);if(o)for(var r of o(e))a.call(e,r)&&s(t,r,e[r]);return t},c=(t,e)=>r(t,n(e)),d=(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 u(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var p,h={exports:{}};var f=(p||(p=1,h.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{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new b,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 y?t.push(...e.errors):t.push(e)}if(t.length)throw new y(t)}}const w=new WeakMap,x=new WeakMap;function k(t){const e=w.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function $(t){return k(t).scope}function E(t){const e=k(t);return e.destroying||e.scope.closed}function T(t,e,r,n,o=!1){var i,a,s;const l=k(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof y?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)?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")),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 C=new WeakMap;function L(t,e){const r=$(t).child();return C.set(e,r),r}function S(t){const e=C.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function P(t){var e;null==(e=C.get(t))||e.dispose()}function M(t,e){return{on:(r,n)=>{!function(t,e,r,n){const o=S(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=S(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)}}const z=null!=(t=null==globalThis?void 0:globalThis.CUSTOM_USER_AGENT)?t:"undefined"!==typeof navigator?navigator.userAgent:"",A=/^(?:(?!chrome|android).)*safari/i.test(z),O=/iPad|iPhone|iPod/i.test(z)&&!window.MSStream,R=O||z.includes("Macintosh")&&navigator.maxTouchPoints>=1,I=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(z)||R,_="undefined"!==typeof window&&"undefined"!==typeof document;function N(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function D(t,e=document){return e.querySelector(t)}function W(t,e=document){return Array.from(e.querySelectorAll(t))}function F(t,e){return t.classList.add(e)}function V(t,e){return t.classList.remove(e)}function Y(t,e){return t.classList.contains(e)}function B(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}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){return Array.from(t.parentElement.children).filter(e=>e!==t)}function U(t,e){q(t).forEach(t=>V(t,e)),F(t,e)}function X(t,e,r="top"){I||(t.setAttribute("aria-label",e),F(t,"hint--rounded"),F(t,`hint--${r}`))}function G(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}function K(t,e){return nt(t).includes(e)}function Z(t,e){return e.parentNode.replaceChild(t,e),t}function J(t){return document.createElement(t)}function Q(t="",e=""){const r=J("i");return F(r,"art-icon"),F(r,`art-icon-${t}`),B(r,e),r}function tt(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function et(t){return t.getBoundingClientRect()}function rt(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function nt(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function ot(){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;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class it extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function at(t,e){if(!t)throw new it(e);return t}function st(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function lt(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function ct(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 dt(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function ut(t){return t.charAt(0).toUpperCase()+t.slice(1)}function pt(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 ht={"&":"&","<":"<",">":">","'":"'",'"':"""},ft={"&":"&","<":"<",">":">","'":"'",""":'"'},mt=/(&|<|>|'|")/g;function gt(t){return t.replace(/[&<>'"]/g,t=>ht[t]||t)}const vt=Object.defineProperty,{hasOwnProperty:yt}=Object.prototype;function bt(t,e){return yt.call(t,e)}function wt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function xt(...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)?xt(o,i):i,vt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function kt(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 $t(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function Et(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")}`}function Tt(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}}const Ct=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:it,addClass:F,append:B,assToVtt:Et,capitalize:ut,clamp:dt,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:ct,errorHandle:at,escape:gt,get:wt,getComposedPath:nt,getExt:lt,getIcon:Q,getRect:et,getSafeAreaInsets:ot,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:bt,hasClass:Y,includeFromEvent:K,inverseClass:U,isBrowser:_,isIOS:O,isIOS13:R,isInViewport:G,isMobile:I,isSafari:A,loadImg:rt,mergeDeep:xt,query:D,queryAll:W,remove:function(t){return t.parentNode.removeChild(t)},removeClass:V,replaceElement:Z,secondToTime:pt,setStyle:H,setStyleText:N,setStyles:j,siblings:q,silencePromise:st,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:kt,supportsFlex:tt,throttle:Tt,tooltip:X,unescape:function(t){return t.replace(mt,t=>ft[t]||t)},userAgent:z,vttToBlob:$t},Symbol.toStringTag,{value:"Module"}));function Lt(t,e){return B(t,e)}function St(t,e){return e.querySelector(t)}const Pt="array",Mt="boolean",zt="string",At="number",Ot="object",Rt="function";function It(t,e,r){return at(e===zt||e===At||t instanceof Element,`${r.join(".")} require '${zt}' or 'Element' type`)}const _t={html:It,disable:`?${Mt}`,name:`?${zt}`,index:`?${At}`,style:`?${Ot}`,click:`?${Rt}`,mounted:`?${Rt}`,tooltip:`?${zt}|${At}`,width:`?${At}`,selector:`?${Pt}`,onSelect:`?${Rt}`,switch:`?${Mt}`,onSwitch:`?${Rt}`,range:`?${Pt}`,onRange:`?${Rt}`,onChange:`?${Rt}`},Nt={id:zt,container:It,url:zt,poster:zt,type:zt,theme:zt,lang:zt,volume:At,isLive:Mt,muted:Mt,autoplay:Mt,autoSize:Mt,autoMini:Mt,loop:Mt,flip:Mt,playbackRate:Mt,aspectRatio:Mt,screenshot:Mt,setting:Mt,hotkey:Mt,pip:Mt,mutex:Mt,backdrop:Mt,fullscreen:Mt,fullscreenWeb:Mt,subtitleOffset:Mt,miniProgressBar:Mt,useSSR:Mt,playsInline:Mt,lock:Mt,gesture:Mt,fastForward:Mt,autoPlayback:Mt,autoOrientation:Mt,airplay:Mt,proxy:`?${Rt}`,plugins:[Rt],layers:[_t],contextmenu:[_t],settings:[_t],controls:[c(l({},_t),{position:(t,e,r)=>{const n=["top","left","right"];return at("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${Mt}`,html:zt,url:zt}],highlight:[{time:At,text:zt}],thumbnails:{url:zt,number:At,column:At,width:At,height:At,scale:At},subtitle:{url:zt,name:zt,type:zt,style:Ot,escape:Mt,encoding:zt,onVttLoad:Rt},moreVideoAttr:Ot,i18n:Ot,icons:Ot,cssVar:Ot,customType:Ot},Dt=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 Y(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?F(e,r):V(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(E(this.art))return;const r="function"===typeof t?t(this.art):t;if(E(this.art))return;if(r.html=r.html||"",m(r,_t),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;at(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=L(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){F(t,`art-${r}`),F(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):B(e,t),i.html&&B(t,i.html),i.style&&j(t,i.style),i.tooltip&&X(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{P(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){at(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Dt.has(e)){Dt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{P(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Dt.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 Ft extends Wt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,L(t,this.$parent),I||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=M(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 c(l({},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}=M(e,t),n=D('[data-value="1"]',t);n&&U(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&U(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 c(l({},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}=M(e,t),n=D('[data-value="default"]',t);n&&U(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(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(ut(t))}`).join("");return c(l({},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}=M(e,t),n=D('[data-value="normal"]',t);n&&U(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>c(l({},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 c(l({},t),{html:`ArtPlayer ${g}`})}({name:"version",index:50})),this.add(function(t){return e=>c(l({},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}=et(e),{height:c,width:d}=et(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),j(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{K(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Vt(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 Yt(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 Bt(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)})})}function Ht(t,e){const{$progress:r}=t.template,{left:n}=et(r),o=dt((I?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:pt(i),width:o,percentage:dt(o/r.clientWidth,0,1)}}function jt(t,e){if(t.isRotate){const r=(e.touches[0].clientY-t.top)/t.height,n=r*t.duration;t.emit("setBar","played",r,e),t.seek=n}else{const{second:r,percentage:n}=Ht(t,e);t.emit("setBar","played",n,e),t.seek=r}}function qt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=S(e),{on:a}=M(t,e);let s=()=>{};const l=St(".art-progress-hover",e),c=St(".art-progress-loaded",e),d=St(".art-progress-played",e),u=St(".art-progress-highlight",e),p=St(".art-progress-indicator",e),h=St(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Ht(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?B(p,r.indicator):H(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&I;if("loaded"===r&&H(c,"width",100*n+"%"),"hover"===r&&(H(l,"width",100*n+"%"),K(a,u)?function(r){const{width:n}=Ht(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?H(h,"left",0):n>e.clientWidth-i/2?H(h,"left",e.clientWidth-i+"px"):H(h,"left",n-i/2+"px")}(a):f(a),0===n?V(o,"art-progress-hover"):F(o,"art-progress-hover")),"played"===r&&(H(d,"width",100*n+"%"),H(p,"left",100*n+"%")),m){F(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:pt(n*t.duration)}),s(),s=Yt(i,()=>{V(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 Ut(t){return e=>c(l({},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}=M(t,e);if(!I){let e=!1;i(r,"click",e=>{e.target!==n&&jt(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=Ht(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=Ht(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function Xt(t){const{option:e}=t.art;e.isLive||t.add(Ut({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Lt(t,o.play),s=Lt(t,o.pause);function l(){H(a,"display","flex"),H(s,"display","none")}function c(){H(a,"display","none"),H(s,"display","flex")}X(a,i.get("Play")),X(s,i.get("Pause")),n(a,"click",()=>{st(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=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o}=e,i=Lt(t,o.volume),a=Lt(t,o.volumeClose),s=Lt(t,'
'),l=Lt(s,'
'),c=Lt(l,'
'),d=Lt(l,'
'),u=Lt(d,'
'),p=Lt(u,'
'),h=Lt(d,'
');function f(t){const{top:e,height:r}=et(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)H(i,"display","none"),H(a,"display","flex"),H(h,"top","100%"),H(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;H(i,"display","flex"),H(a,"display","none"),H(h,"top",100-t+"%"),H(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}),I)H(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=>c(l({},t),{style:I?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=M(e,t);function n(){const r=`${pt(e.currentTime)} / ${pt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!$(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!I&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=M(e,t),{icons:n}=e;Lt(t,n.screenshot),r(t,"click",()=>{e.screenshot()})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e;Lt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{X(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e;Lt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{X(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=>c(l({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=M(e,t),{icons:n}=e;Lt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Lt(t,o.fullscreenWebOn),s=Lt(t,o.fullscreenWebOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(X(t,i.get("Exit Web Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(X(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=>c(l({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Lt(t,o.fullscreenOn),s=Lt(t,o.fullscreenOff);H(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(X(t,i.get("Exit Fullscreen")),H(a,"display","none"),H(s,"display","inline-flex")):(X(t,i.get("Fullscreen")),H(a,"display","inline-flex"),H(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rKt.get(t).option.selector}),vt(t,"$control_item",{get:()=>Kt.get(t).item}),vt(t,"$control_value",{get:()=>Kt.get(t).value})),Kt.set(t,e)}function Jt(t,e){t.innerHTML=e}function Qt(t,e,r,n,o){const{proxy:i}=t.events,a=S(n),s=r.selector;F(n,"art-control-selector");const l=document.createElement("div");F(l,"art-selector-value"),B(l,r.html),n.textContent="",B(n,l);const c=Lt(n,'
');for(let d=0;dd(null,null,function*(){if(a.closed)return;const o=nt(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 Gt.set(t,e),()=>{Gt.get(t)===e&&Gt.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()&&Jt(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class te 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;L(t,n);const{on:o}=M(t,n);o("mousemove",()=>{I||(this.show=!0)}),o("click",()=>{I?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=K(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?(V(r,"art-hide-cursor"),F(r,"art-hover"),this.timer=Date.now()):(F(r,"art-hide-cursor"),V(r,"art-hover"))}),this.init(),$(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=S(e),{on:i}=M(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(){Xt(this)}add(t){if(E(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:at(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Jt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function ee(t,e,r,n){const o=e-n,i=r-t;let a=0;if(Math.abs(i)<2&&Math.abs(o)<2)return a;const s=function(t,e){return 180*Math.atan2(e,t)/Math.PI}(i,o);return s>=-45&&s<45?a=4:s>=45&&s<135?a=1:s>=-135&&s<-45?a=2:(s>=135&&s<=180||s>=-180&&s<-135)&&(a=3),a}function re(t){if(t.constructor.USE_RAF){const e=$(t);let r=()=>{};!function n(){t.playing&&t.emit("raf"),t.isDestroy||(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))}(),t.on("destroy",()=>{r()})}}const ne=new WeakMap;class oe{constructor(t){this.destroyEvents=new Set;const e=$(t);ne.set(this,e),e.add(()=>this.destroy()),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),function(t,e){const{constructor:r,template:{$player:n,$video:o}}=t;function i(e){K(e,n)?(t.isInput="INPUT"===e.target.tagName,t.isFocus=!0,t.emit("focus",e)):(t.isInput=!1,t.isFocus=!1,t.emit("blur",e))}t.on("document:click",i),t.on("document:contextmenu",i);let a=[];e.proxy(o,"click",e=>{const n=Date.now();a.push(n);const{MOBILE_CLICK_PLAY:o,DBCLICK_TIME:i,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=a.filter(t=>n-t<=i);switch(c.length){case 1:t.emit("click",e),I?!t.isLock&&o&&st(t.toggle()):st(t.toggle()),a=c;break;case 2:t.emit("dblclick",e),I?!t.isLock&&s&&st(t.toggle()):l&&(t.fullscreen=!t.fullscreen),a=[];break;default:a=[]}})}(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{F(r,"art-hover"),t.emit("hover",!0,e)},e=>{V(r,"art-hover"),t.emit("hover",!1,e)})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t;t.on("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),t.aspectRatio=e,n.show=""});const o=$(t);let i=()=>{};const a=()=>{i(),i=Yt(o,()=>t.emit("resize"),n.RESIZE_TIME)};t.on("window:orientationchange",()=>a()),t.on("window:resize",()=>a()),screen&&screen.orientation&&screen.orientation.onchange&&e.proxy(screen.orientation,"change",()=>a())}(t,this),function(t,e){if(I&&!t.option.isLive){const{$video:r,$progress:n}=t.template;let o=null,i=!1,a=0,s=0,l=0;const c=e=>{if(1===e.touches.length&&!t.isLock){o===n&&jt(t,e),i=!0;const{pageX:r,pageY:c}=e.touches[0];a=r,s=c,l=t.currentTime}},d=e=>{if(1===e.touches.length&&i&&t.duration){const{pageX:n,pageY:i}=e.touches[0],c=ee(a,s,n,i),d=[3,4].includes(c),u=[1,2].includes(c);if(d&&!t.isRotate||u&&t.isRotate){const c=dt((n-a)/t.width,-1,1),d=dt((i-s)/t.height,-1,1),u=t.isRotate?d:c,p=o===r?t.constructor.TOUCH_MOVE_RATIO:1,h=dt(l+t.duration*u*p,0,t.duration);t.seek=h,t.emit("setBar","played",dt(h/t.duration,0,1),e),t.notice.show=`${pt(h)} / ${pt(t.duration)}`}}},u=()=>{i&&(a=0,s=0,l=0,i=!1,o=null)};t.option.gesture&&(e.proxy(r,"touchstart",t=>{o=r,c(t)}),e.proxy(r,"touchmove",d)),e.proxy(n,"touchstart",t=>{o=n,c(t)}),e.proxy(n,"touchmove",d),t.on("document:touchend",u)}}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=Tt(()=>{t.emit("view",G(n,r.SCROLL_GAP))},r.SCROLL_TIME);t.on("window:scroll",()=>o()),t.on("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){const r=["click","mouseup","keydown","touchend","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],n=["resize","scroll","orientationchange"],o=[];function i(i={}){for(let t=0;t{const n=i.document||a.ownerDocument||document,s=e.proxy(n,r,e=>{t.emit(`document:${r}`,e)});o.push(s)}),n.forEach(r=>{var n;const s=i.window||(null==(n=a.ownerDocument)?void 0:n.defaultView)||window,l=e.proxy(s,r,e=>{t.emit(`window:${r}`,e)});o.push(l)})}i(),e.bindGlobalEvents=i}(t,this),re(t)}proxy(t,e,r,n={}){if(Array.isArray(e))return e.map(e=>this.proxy(t,e,r,n));if(ne.get(this).closed)return()=>{};t.addEventListener(e,r,n);const o=()=>t.removeEventListener(e,r,n);return this.destroyEvents.add(o),o}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){if(this.destroyEvents.has(t))try{t()}catch(e){console.warn("Failed to remove event listener:",e)}finally{this.destroyEvents.delete(t)}}destroy(){for(const e of this.destroyEvents)try{e()}catch(t){console.warn("Failed to destroy event listener:",t)}this.destroyEvents.clear()}}class ie{constructor(t){this.art=t,this.keys={},I||this.init()}init(){const{constructor:t}=this.art;this.art.option.hotkey&&(this.add("Escape",()=>{this.art.fullscreenWeb&&(this.art.fullscreenWeb=!1)}),this.add("Space",()=>{st(this.art.toggle())}),this.add("ArrowLeft",()=>{this.art.backward=t.SEEK_STEP}),this.add("ArrowUp",()=>{this.art.volume+=t.VOLUME_STEP}),this.add("ArrowRight",()=>{this.art.forward=t.SEEK_STEP}),this.add("ArrowDown",()=>{this.art.volume-=t.VOLUME_STEP})),this.art.on("document:keydown",t=>{if(this.art.isFocus){const e=document.activeElement.tagName.toUpperCase(),r=document.activeElement.getAttribute("contenteditable");if("INPUT"!==e&&"TEXTAREA"!==e&&""!==r&&"true"!==r&&!t.altKey&&!t.ctrlKey&&!t.metaKey&&!t.shiftKey){const e=this.keys[t.code];if(e){t.preventDefault();for(let r=0;r\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 ce{constructor(t){const e=l(l({},le),t.option.icons);for(const r in e)vt(this,r,{get:()=>Q(r,e[r])})}}class de extends Wt{constructor(t){super(t),this.name="info",I||this.init()}init(){const{proxy:t,constructor:e,template:{$infoPanel:r,$infoClose:n,$video:o}}=this.art;t(n,"click",()=>{this.show=!1});let i=()=>{};const a=W("[data-video]",r)||[];this.art.on("destroy",()=>i());const s=$(this.art);!function t(){for(let e=0;e{H(o,"display","none"),H(i,"display",null)}),n.proxy(e.$state,"click",()=>st(t.play()))}}class fe{constructor(t){this.art=t,this.timer=null,$(t).add(()=>this.destroy()),t.on("destroy",()=>this.destroy())}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}set show(t){if($(this.art).closed)return;const{constructor:e,template:{$player:r,$noticeInner:n}}=this.art;t?(n.textContent=t instanceof Error?t.message.trim():t,F(r,"art-notice-show"),clearTimeout(this.timer),this.timer=setTimeout(()=>{n.textContent="",V(r,"art-notice-show")},e.NOTICE_TIME)):V(r,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function me({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function ge(t,e){if(!me(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 me(r)?r:void 0}function ve(t){const{$container:e,$video:r}=t.template;vt(t,"autoHeight",{value(){if(E(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!me(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||E(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function ye(t,e,r,n=!1){const o=e=>{E(t)||r(e)};t[n?"once":"on"](e,o),$(t).add(()=>{t.off(e,o)})}function be(t,e,r){for(const[n,o]of e){if(E(t)||r&&!r())return;t[n].show=o}}const we=new WeakMap,xe=new WeakMap,ke=new WeakMap;function $e(t){return ke.get(t)||$(t)}function Ee(t){const e=we.get(t),r=ke.get(t);return()=>we.get(t)===e&&(!e||e.active())&&ke.get(t)===r&&(!r||!r.closed)}function Te(t){const e=ke.get(t),r=$(t).child(),n=r.child();ke.set(t,r),r.add(()=>{ke.get(t)===r&&ke.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!E(t)&&!n.closed&&we.get(t)===o};return we.set(t,o),n.add(()=>{we.get(t)===o&&we.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function Ce(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function Le(t,e,r){xe.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{xe.get(t)===e&&(xe.delete(t),Ce(e))}}function Se(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Pe(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=$e(t),l=0;return{reset(){l=0,null==a||a.dispose(),V(i,"art-error")},loadStart(){V(i,"art-error")},schedule(c){(c=>d(null,null,function*(){if(E(t))return;const d=$e(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!E(t)&&!u.closed&&d===$e(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Me(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{E(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Pe(t);!function(t,e){ye(t,"video:canplay",()=>{e.reset(),be(t,[["loading",!1]])}),ye(t,"video:canplay",()=>{be(t,[["loading",!1],["controls",!0],["mask",!0]]),E(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;ye(t,"video:ended",()=>{if(e.loop){const e=Ee(t);if(t.seek=0,E(t)||!e())return;st(t.play()),e()&&be(t,[["controls",!1],["mask",!1]],e)}else be(t,[["controls",!0],["mask",!0]])})}(t),ye(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;ye(t,"video:loadedmetadata",()=>{t.emit("resize"),I&&be(t,[["loading",!1],["controls",!0],["mask",!0]])}),ye(t,"video:loadstart",()=>{e.loadStart(),be(t,[["loading",!0],["mask",!1],["controls",!0]])}),ye(t,"video:pause",()=>{be(t,[["controls",!0],["mask",!0]])}),ye(t,"video:play",()=>{be(t,[["mask",!1]]),E(t)||H(r,"display","none")}),ye(t,"video:playing",()=>be(t,[["mask",!1]])),ye(t,"video:progress",()=>{t.playing&&be(t,[["loading",!1]])}),ye(t,"video:seeked",()=>be(t,[["loading",!1],["mask",!0]])),ye(t,"video:seeking",()=>be(t,[["loading",!0],["mask",!1]])),ye(t,"video:timeupdate",()=>be(t,[["mask",!1]])),ye(t,"video:waiting",()=>be(t,[["loading",!0],["mask",!1]]))}(t,e)}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})(),Oe={change:Ae.fullscreenchange,error:Ae.fullscreenerror},Re={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Re.off("change",o),r()};Re.on("change",o);const i=t[Ae.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Re.isFullscreen)return void t();const r=()=>{Re.off("change",r),t()};Re.on("change",r);const n=document[Ae.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Re.isFullscreen?Re.exit():Re.request(t,e),onchange(t){Re.on("change",t)},onerror(t){Re.on("error",t)},on(t,e){const r=Oe[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Oe[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(Re,{isFullscreen:{get:()=>Boolean(document[Ae.fullscreenElement])},element:{enumerable:!0,get:()=>document[Ae.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Ae.fullscreenEnabled])}});const _e=new WeakMap;function Ne(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function De(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=_e.get(t);if(!n){n=new WeakMap,_e.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Ne(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Ne(i))}function We(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&&De(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Vt(i,t.document,t.changeEvent,m),Vt(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=_e.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&&De(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 Fe(t,e){const r=$(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()}),Vt(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=_e.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||E(t))return;s=r;const o=l,a=()=>E(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")))}),Vt(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!E(t)&&t.emit("fullscreenError",r)}),{get:()=>!E(t)&&i(),set(n){if(E(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=We(e,r,c,()=>{!E(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw E(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){var e;if(Ve.has(this)&&Ye(this,"webkitbeginfullscreen"===t.type)){Be(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function je(t){Ve.add(t),t.addEventListener("webkitbeginfullscreen",He),t.addEventListener("webkitpresentationmodechanged",He)}function qe(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=Ye(e),i=o,a=!1,s=0;const l=()=>Ye(e,n);function c(r){if(E(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 u=s,p=()=>E(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&&je(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Vt(r,e,"webkitbeginfullscreen",()=>c(!0)),Vt(r,e,"webkitendfullscreen",()=>c(!1)),Vt(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!E(t)&&l(),set(r){if(E(t))return;const n=++s;if(i=Boolean(r),r){if(Be(e),t.state="fullscreen",E(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){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(E(t))return;const i=function(t){const e=Re.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?vt(t,"fullscreen",Fe(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?vt(t,"fullscreen",qe(t)):vt(t,"fullscreen",{get:()=>!1,set(){E(t)||(r.show=e.get("Fullscreen Not Supported"))}}),vt(t,"fullscreen",wt(t,"fullscreen"))};t.once("video:loadedmetadata",i),$(t).add(()=>{t.off("video:loadedmetadata",i)})}function Xe(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Ge({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 Ke(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()&&(Ge(t.placement),r()))}return $(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 y([a,s])}throw a}}),i=>{if(E(t))return;const a=++n,s=()=>a===n&&!E(t);if(i){r||(r={placement:Xe(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);vt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function Ze(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 Je(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Qe(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),Vt(o,e,"click",n),Vt(o,l,"click",()=>{st(t.play())}),Vt(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=""};Vt(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=Ze(i.left,i.top,Je(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 tr(t){const{$player:e,$video:r}=t.template,n=$(t).child();let o,i,a=0,s=!1,d=!1;const u=()=>!E(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{Ge(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(E(t))return;const r=++a;d=!1,p(),E(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(E(t))return;const m=++a;if(s)d=!0;else if(t.state="mini",!E(t)&&m===a){null!=i||(i=Xe(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Qe(t,n,u,h)}finally{s=!1}}if(d)return d=!1,void f();if(!o||E(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),E(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}:c(l({},Ze(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,Je(o.element));if(E(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),E(t)||m!==a)return;t.storage.set("left",i.left)}E(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,E(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 er=new WeakSet,rr=t=>"picture-in-picture"===t.webkitPresentationMode;function nr(t){er.delete(t),t.removeEventListener("webkitpresentationmodechanged",or),t.removeEventListener("enterpictureinpicture",or)}function or(){var t;if(er.has(this)&&rr(this)){nr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function ir(t){er.add(t),t.addEventListener("webkitpresentationmodechanged",or),t.addEventListener("enterpictureinpicture",or)}function ar(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=$(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||!E(t)&&a||d()},e=>{E(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Vt(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!E(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Vt(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!E(t)&&o()?e:null,set(n){if(E(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",E(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=$(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(E(t)||er.has(e))return;const s=rr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),E(t)||i!==l||rr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&ir(e),rr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Vt(r,e,l,()=>s());return{get:()=>!E(t)&&rr(e),set(r){var n;if(E(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(nr(e),t.state="pip",E(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,ir(e)),rr(e)&&e.webkitSetPresentationMode("inline");E(t)||l!==i||c!==a||rr(e)!==Boolean(r)||s(!0)}}}(t)):vt(t,"pip",{get:()=>!1,set(){E(t)||(r.show=e.get("PIP Not Supported"))}})}function sr(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 d(this,null,function*(){const r=function(t){return t&&Gt.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!E(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!E(t)&&r()&&(n.show=i)}return e.html})}})}})}function lr(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 cr(t,e,r){return new Promise((n,o)=>{if(E(t)||e===t.url)return void n();const i=Te(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(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child(),h={"video:error":u,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){u(e)}},"video:canplay":()=>{if(!c())return;p.dispose();d(null,null,function*(){if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{yield t.play()}catch(e){}c()&&(t.notice.show="",l())}}).catch(u)}},f=a.child(),m=[],g=Object.keys(h);for(const e of g)lr(f,t,e,t=>{i.acceptingEvents&&m.push([e,t])},!1);if(Le(t,i,e),!c())return;if(t.notice.show="",!c())return;const v=()=>{if(f.dispose(),!e)return void l();const r={};for(const e of g)r[e]=lr(p,t,e,h[e]);for(const[t,e]of m){if(!c()||p.closed)break;r[t](e)}m.length=0};i.assigned?v():i.onAssigned=v}catch(p){u(p)}})}function dr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",(o,s,l)=>d(null,null,function*(){var c;const d=null==(c=t.controls)?void 0:c.thumbnails,{url:u,scale:p}=e.thumbnails;if(!d||!u)return;if("hover"===o||"played"===o&&l&&I){if(a||i||(i=!0,a=yield rt(u,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-h/2?H(s,"left",r.clientWidth-h+"px"):H(s,"left",o-h/2+"px")}(o)}})),vt(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function ur(t){const{option:e,template:{$video:r}}=t;vt(t,"url",{get:()=>r.src,set(n){return d(this,null,function*(){if(E(t))return;const o=function(t){const e=xe.get(t);return xe.delete(t),e||Te(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield Bt(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||lt(n),s=e.customType[a];if(a&&s){if(!(yield Bt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;lr(l,t,"video:canplay",()=>{c=!d}),lr(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=>Se(o,t))}else{if(i&&URL.revokeObjectURL(i),!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||lr(o.scope,t,"video:canplay",e)}}catch(i){Se(o,i)}finally{Ce(o)}})}})}class pr{constructor(t){ur(t),function(t){const{template:{$video:e}}=t;vt(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;vt(t,"play",{value(){return d(this,null,function*(){const a=Ee(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()})}(t),function(t){const{notice:e}=t;vt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${pt(t.currentTime)} / ${pt(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}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;vt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=dt(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)}})}(t),function(t){const{$video:e}=t.template;vt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=dt(n,0,t.duration))}})}(t),function(t){vt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>cr(t,e,0);vt(t,"switchQuality",{value:e=>cr(t,e,t.currentTime)}),vt(t,"switchUrl",{value:e}),vt(t,"switch",{set:e})}(t),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}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;vt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!E(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=ge({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(E(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}`,E(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=J("canvas");vt(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),vt(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),vt(t,"screenshot",{value:e=>d(null,null,function*(){const n=yield t.getDataURL();return ct(n,`${e||`artplayer_${pt(r.currentTime)}`}.png`),t.emit("screenshot",n),n})})}(t),Ue(t),Ke(t),ar(t),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})}(t),function(t){vt(t,"played",{get:()=>t.currentTime/t.duration})}(t),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)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;vt(t,"autoSize",{value(){if(E(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!me(o))return;const i=et(e),a=ge(i,o.width/o.height);a&&!E(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}))}})}(t),function(t){const e=t;vt(t,"rect",{get:()=>et(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})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;vt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){E(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(ut(o))}`,E(t)||t.emit("flip",o))}})}(t),function(t){vt(t,"mini",tr(t))}(t),function(t){const{template:{$poster:e}}=t;vt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){H(e,"backgroundImage",`url(${t})`)}})}(t),ve(t),function(t){const{$player:e}=t.template;vt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){vt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){vt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),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{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,vt(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),sr(t),dr(t),Me(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=dt(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=dt(i,0,1)),e.poster&&H(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const hr=new WeakMap,fr="art-auto-orientation-fullscreen";function mr(t){if(hr.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const gr="art-auto-orientation",vr=["width","height","transform-origin","transform"];function yr(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 me(t)&&me(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=$(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(gr);r.classList.remove(gr),n&&(t.isRotate=!1,E(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=ot();if(E(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=vr.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(gr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;E(t)||(r?o?s(!1):e()&&(i(),i=Yt(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(fr),t&&(t.cancelled=!0,mr(t),t.settled&&hr.get(t.orientation)===t&&hr.delete(t.orientation))}return $(t).add(o),i=>{var a,s;if(E(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=()=>!E(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(fr),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(fr):(mr(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),$(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function br(t){const{i18n:e,icons:r,storage:n,constructor:o,proxy:i,template:{$poster:a}}=t,s=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '}),l=D(".art-auto-playback-last",s),c=D(".art-auto-playback-jump",s),d=D(".art-auto-playback-close",s);B(d,r.close);let u=null;function p(){const r=(n.get("times")||{})[t.option.id||t.option.url];clearTimeout(u),H(s,"display","none"),r&&r>=o.AUTO_PLAYBACK_MIN&&(H(s,"display","flex"),l.textContent=`${e.get("Last Seen")} ${pt(r)}`,c.textContent=e.get("Jump Play"),i(d,"click",()=>{H(s,"display","none")}),i(c,"click",()=>{t.seek=r,st(t.play()),H(a,"display","none"),H(s,"display","none")}),t.once("video:timeupdate",()=>{u=setTimeout(()=>{H(s,"display","none")},o.AUTO_PLAYBACK_TIMEOUT)}))}return t.on("video:timeupdate",()=>{if(t.playing){const e=n.get("times")||{},r=Object.keys(e);r.length>o.AUTO_PLAYBACK_MAX&&delete e[r[0]],e[t.option.id||t.option.url]=t.currentTime,n.set("times",e)}}),t.on("ready",p),t.on("restart",p),{name:"auto-playback",get times(){return n.get("times")||{}},clear:()=>n.del("times"),delete(t){const e=n.get("times")||{};return delete e[t],n.set("times",e),e}}}function wr(t){const{constructor:e,proxy:r,template:{$player:n,$video:o}}=t;let i=null,a=!1,s=1;const l=()=>{clearTimeout(i),a&&(a=!1,t.playbackRate=s,V(n,"art-fast-forward"))};return r(o,"touchstart",r=>{1===r.touches.length&&t.playing&&!t.isLock&&(i=setTimeout(()=>{a=!0,s=t.playbackRate,t.playbackRate=e.FAST_FORWARD_VALUE,F(n,"art-fast-forward")},e.FAST_FORWARD_TIME))}),t.on("document:touchmove",l),t.on("document:touchend",l),{name:"fastForward",get state(){return Y(n,"art-fast-forward")}}}function xr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return Y(n,"art-lock")}function i(){F(n,"art-lock"),t.isLock=!0,t.emit("lock",!0)}function a(){V(n,"art-lock"),t.isLock=!1,t.emit("lock",!1)}return e.add({name:"lock",mounted(e){const n=B(e,r.lock),o=B(e,r.unlock);H(n,"display","none"),t.on("lock",t=>{t?(H(n,"display","inline-flex"),H(o,"display","none")):(H(n,"display","none"),H(o,"display","inline-flex"))})},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function kr(t){return t.on("control",e=>{e?V(t.template.$player,"art-mini-progress-bar"):F(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class $r{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){E(t.art)||!e.miniProgressBar||e.isLive||t.add(kr),!E(t.art)&&e.lock&&I&&t.add(xr),E(t.art)||!e.autoPlayback||e.isLive||t.add(br),!E(t.art)&&e.autoOrientation&&I&&t.add(yr),!E(t.art)&&e.fastForward&&I&&!e.isLive&&t.add(wr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){at(!E(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(E(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(E(t.art))return t;let o=n;const i=bt(t,o);if(E(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return E(t.art)||(at(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),E(t.art)||vt(t,o,{value:r})),t}(this,t,e)}}const Er=new WeakMap;function Tr(t){return!t.closed&&!Er.get(t)}function Cr(t){Er.set(t,(Er.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Er.get(t)||1)-1;r?Er.set(t,r):Er.delete(t)}}const Lr=new WeakMap,Sr=new WeakMap,Pr=["$parent","$parents","$option","$events","$formatted"];function Mr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Lr.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=Lr.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function zr(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 Ar(t){const e=Lr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Or(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>Fr(t,o)])try{e()}catch(d){d instanceof y?l.push(...d.errors):l.push(d)}if(r.closed||E(t)||(o.push(...i.splice(0)),Wr.set(r,o),Nr.set(e,r),Dr.set(e,n)),a(),l.length)throw new y(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function jr(t,e,r,n,o,i){const a=i||Yr(e);if(!Tr(a)||E(t))return;const s=t.proxy(r,n,e=>{if(Tr(a)&&!E(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Tr(a)||E(t)?t.events.remove(s):(Ar(e).events.push(s),i&&i!==Nr.get(e)&&i.add(()=>{const r=Ar(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function qr(t,e,r,n){const o=Yr(e);if(!Tr(o)||E(t))return;const i=(...e)=>{if(Tr(o)&&!E(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Ur(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||I||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const Xr=new WeakMap;function Gr(t){Xr.delete(t)}const Kr=new WeakMap;function Zr(t,e){e?Kr.set(t,e):Kr.delete(t)}function Jr(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=Kr.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(),Zr(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 Qr=new WeakMap;function tn(t,e,r,n,o,i,a,s){return d(this,null,function*(){try{const l=Yr(e),c=Yr(i),d=(Qr.get(i)||0)+1;Qr.set(i,d);const u=()=>Tr(l)&&Tr(c)&&!E(t.art)&&Qr.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 en(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 nn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof y?e.push(...r.errors):e.push(r)}if(e.length)throw new y(e)}function on(t){var e;null==(e=rn.get(t))||e()}function an(t,e){const r=t.find(e.name);if(E(t.art))return r||e;if(!r)return t.add(e);Gr(r),on(r);const n=Jr(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?en(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=Hr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Cr(Ir(t)))}catch(l){try{nn([...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,nn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,nn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>_r(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)rn.get(t)===h&&rn.delete(t);if(E(t.art))return void d.dispose();const e=r.$item;try{nn([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)&&U(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&&!E(t.art)&&rn.get(r)===h;for(const v of d.items)rn.set(v,h);const m=$(t.art).add(()=>{u=!1;for(const t of d.items)rn.get(t)===h&&rn.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)rn.get(t)===h&&rn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const sn=new WeakMap;function ln(t,e,r){vt(t,`$${e}`,{configurable:!0,get:()=>r}),vt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",B(r,t)}})}function cn(t,e,r=!1){var n,o;const i=function(t){const e=rn.get(t);return()=>!e||rn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";bt(e,"switch")&&(l="switch"),bt(e,"range")&&(l="range"),bt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=$(t)){const n=Nr.get(e);(!n||Tr(n)||n.closed)&&Br(t,e);const o=r.child();return Nr.set(e,o),Dr.set(e,r),Wr.set(o,Ar(e).events),o.add(()=>{Fr(t,Wr.get(o))}),o}(t.art,e,Ir(a)),p=()=>Tr(u)&&!E(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(Zr(e),F(h,"art-setting-item"),H(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=B(h,'
'),f=B(h,'
'),m=document.createElement("div");switch(F(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;B(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;B(m,t)}else B(m,c.check)}if(B(i,m),!p())return;ln(e,"icon",m);const g=document.createElement("div");F(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;B(g,v),B(i,g),ln(e,"html",g);const y=document.createElement("div");F(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(B(y,b),B(f,y),ln(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");F(t,"art-setting-item-right-icon");const r=B(t,c.switchOn),n=B(t,c.switchOff),o=e.switch;if(!p())return;H(o?n:r,"display","none"),B(f,t),vt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;Zr(e,()=>{const t=i;return()=>{i=t}}),vt(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");F(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",B(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))}F(r,"art-setting-range"),B(f,t),vt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;Zr(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");F(t,"art-setting-item-right-icon"),B(t,c.arrowRight),B(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=Yr(e),a=(t,r,n)=>jr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>tn(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=>tn(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 tn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&F(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>tn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,h,l),!p())return;vt(e,"$item",{configurable:!0,get:()=>h}),r&&(null==s?void 0:s.parentNode)?s.replaceWith(h):B(a,h),e.mounted&&p()&&Yt(u,()=>{var r;if(!E(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 dn(t,e=t.option){var r;if(E(t.art))return;const n=t.cache.get(e);if(n&&!Tr(Ir(n)))return;const o=(sn.get(t)||0)+1;sn.set(t,o);const i=()=>sn.get(t)===o&&!E(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)&&U(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{U(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Ir(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=$(t.art).child();return Rr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!E(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;F(n,"art-setting-panel"),B(t.$parent,n),U(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Sr.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=$(e).child(),n=(t,n)=>{if(r.closed||E(e))return;const o=(...t)=>{if(!r.closed&&!E(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=K(r,e.controls.setting),o=K(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||E(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(),qr(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(),qr(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(ut(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(),qr(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)=>{qr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Or(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&&U(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=Sr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;oAr(t).parent},$parents:{get:()=>Ar(t).parents},$option:{get:()=>Ar(t).option},$events:{get:()=>Ar(t).events},$formatted:{get:()=>!0}}),Lr.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 Or(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){Ur(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&&_r(n)}catch(i){r.push(i)}}try{Br(t.art,e)}catch(i){i instanceof y?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new y(r)}(this,t)}remove(t){const e=this.find(t);at(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Gr(t),on(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 y?o.push(...i.errors):o.push(i)}if(o.length)throw new y(o)}update(t){return an(this,t)}add(t,e=this.option){var r;if(E(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={};Xr.set(t,e);const r=()=>Xr.get(t)===e;return{current:r,finish(){r()&&Xr.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(E(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");H(i,"height",`${o}px`),F(i,"art-setting-item"),F(i,"art-setting-item-back");const a=B(i,'
'),s=document.createElement("div");F(s,"art-setting-item-left-icon"),B(s,n),B(a,s),B(a,e.$parent.html),jr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Ir(r)),B(r,i)}(this,t)}createItem(t,e=!1){cn(this,t,e)}render(t=this.option){dn(this,t)}}class hn{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 fn='.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 mn{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 d(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const gn=new WeakMap;function vn(t){return gn.get(t)}function yn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const bn=Wt;class wn extends bn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=$(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return gn.set(t,n),r.add(()=>{yn(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?j(r,t):H(r,t,e)}update(){!function(t){const e=vn(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?gt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return d(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=c(l(l({},o.subtitle),e),{url:t}),a=vn(this),s=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=vn(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&&yn(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 d(this,null,function*(){const e=vn(this),r=function(t){const e=t.request,r=new mn(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(()=>d(this,null,function*(){if(!this.textTrack)return null;if(m(t,Nt.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||lt(e.url)){case"srt":return{vtt:e.onVttLoad(kt(r))};case"ass":return{vtt:e.onVttLoad(Et(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=$t(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 xn=`\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
${g}
\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 kn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=D(e.container),at(this.$container,`No container element found by ${e.container}`)),at(tt(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();at("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),at(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=x.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=k(t);o.rollback=r,x.set(e,t),o.releaseContainer=()=>{x.get(e)===t&&x.delete(e)}}(t,this.$container,en(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return xn}query(t){return D(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=kn.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);!function(t){at(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&&F(this.$player,"art-backdrop"),I&&F(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":F(this.$player,"art-destroy")}}const $n=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class En{on(t,e,r){const n=this.e||(this.e={});let o=$n(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=($n(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=$n(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;ie.call(this,this)),Ln.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Ln.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=k(t);return e.rollback=void 0,!e.scope.closed})(this)&&Cn.push(this)}catch(n){try{T(this,Cn,!0,Ln.REMOVE_SRC_WHEN_DESTROY,!0)}catch(o){console.warn("Failed to clean up ArtPlayer initialization:",o)}throw n}}static get instances(){return Cn}static get version(){return g}static get config(){return v}static get utils(){return Ct}static get scheme(){return Nt}static get Emitter(){return En}static get validator(){return m}static get kindOf(){return m.kindOf}static get html(){return kn.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:A?"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){T(this,Cn,t,Ln.REMOVE_SRC_WHEN_DESTROY)}}return Ln.STYLE=fn,Ln.DEBUG=!1,Ln.CONTEXTMENU=!0,Ln.NOTICE_TIME=2e3,Ln.SETTING_WIDTH=250,Ln.SETTING_ITEM_WIDTH=200,Ln.SETTING_ITEM_HEIGHT=35,Ln.RESIZE_TIME=200,Ln.SCROLL_TIME=200,Ln.SCROLL_GAP=50,Ln.AUTO_PLAYBACK_MAX=10,Ln.AUTO_PLAYBACK_MIN=5,Ln.AUTO_PLAYBACK_TIMEOUT=3e3,Ln.RECONNECT_TIME_MAX=5,Ln.RECONNECT_SLEEP_TIME=1e3,Ln.CONTROL_HIDE_TIME=3e3,Ln.DBCLICK_TIME=300,Ln.DBCLICK_FULLSCREEN=!0,Ln.MOBILE_DBCLICK_PLAY=!0,Ln.MOBILE_CLICK_PLAY=!1,Ln.AUTO_ORIENTATION_TIME=200,Ln.INFO_LOOP_TIME=1e3,Ln.FAST_FORWARD_VALUE=3,Ln.FAST_FORWARD_TIME=1e3,Ln.TOUCH_MOVE_RATIO=.5,Ln.VOLUME_STEP=.1,Ln.SEEK_STEP=5,Ln.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Ln.ASPECT_RATIO=["default","4:3","16:9"],Ln.FLIP=["normal","horizontal","vertical"],Ln.FULLSCREEN_WEB_IN_BODY=!0,Ln.LOG_VERSION=!0,Ln.USE_RAF=!1,Ln.REMOVE_SRC_WHEN_DESTROY=!0,_&&(window.Artplayer=Ln,N("artplayer-style",fn),setTimeout(()=>{Ln.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Ln.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Ln}); +!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,e=Object.defineProperty,r=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,l=(t,e)=>{for(var r in e||(e={}))i.call(e,r)&&s(t,r,e[r]);if(o)for(var r of o(e))a.call(e,r)&&s(t,r,e[r]);return t},c=(t,e)=>r(t,n(e)),d=(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 u(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var p,h={exports:{}};var f=(p||(p=1,h.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{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new b,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 y?t.push(...e.errors):t.push(e)}if(t.length)throw new y(t)}}const w=new WeakMap,x=new WeakMap;function k(t){const e=w.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function $(t){return k(t).scope}function E(t){const e=k(t);return e.destroying||e.scope.closed}function T(t,e,r,n,o=!1){var i,a,s;const l=k(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof y?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)?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")),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 C=new WeakMap;function L(t,e){const r=$(t).child();return C.set(e,r),r}function S(t){const e=C.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function P(t){var e;null==(e=C.get(t))||e.dispose()}function M(t,e){return{on:(r,n)=>{!function(t,e,r,n){const o=S(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=S(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)}}const z=null!=(t=null==globalThis?void 0:globalThis.CUSTOM_USER_AGENT)?t:"undefined"!==typeof navigator?navigator.userAgent:"",A=/^(?:(?!chrome|android).)*safari/i.test(z),O=/iPad|iPhone|iPod/i.test(z)&&!window.MSStream,R=O||z.includes("Macintosh")&&navigator.maxTouchPoints>=1,I=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(z)||R,_="undefined"!==typeof window&&"undefined"!==typeof document;function N(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function D(t,e=document){return e.querySelector(t)}function F(t,e=document){return Array.from(e.querySelectorAll(t))}function W(t,e){return t.classList.add(e)}function V(t,e){return t.classList.remove(e)}function Y(t,e){return t.classList.contains(e)}function B(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function j(t,e,r){return t.style[e]=r,t}function H(t,e){for(const r in e)j(t,r,e[r]);return t}function q(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function U(t,e){q(t).forEach(t=>V(t,e)),W(t,e)}function X(t,e,r="top"){I||(t.setAttribute("aria-label",e),W(t,"hint--rounded"),W(t,`hint--${r}`))}function G(t,e){return rt(t).includes(e)}function K(t,e){return e.parentNode.replaceChild(t,e),t}function Z(t){return document.createElement(t)}function J(t="",e=""){const r=Z("i");return W(r,"art-icon"),W(r,`art-icon-${t}`),B(r,e),r}function Q(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function tt(t){return t.getBoundingClientRect()}function et(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function rt(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function nt(){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;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}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:W,append:B,assToVtt:$t,capitalize:dt,clamp:ct,createElement:Z,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:rt,getExt:st,getIcon:J,getRect:tt,getSafeAreaInsets:nt,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:Y,includeFromEvent:G,inverseClass:U,isBrowser:_,isIOS:O,isIOS13:R,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:I,isSafari:A,loadImg:et,mergeDeep:wt,query:D,queryAll:F,remove:function(t){return t.parentNode.removeChild(t)},removeClass:V,replaceElement:K,secondToTime:ut,setStyle:j,setStyleText:N,setStyles:H,siblings:q,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:Q,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:X,unescape:function(t){return t.replace(ft,t=>ht[t]||t)},userAgent:z,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function Tt(t,e){return B(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:[c(l({},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},_t=new WeakSet;class Nt{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 Y(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?W(e,r):V(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(E(this.art))return;const r="function"===typeof t?t(this.art):t;if(E(this.art))return;if(r.html=r.html||"",m(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=L(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){W(t,`art-${r}`),W(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):B(e,t),i.html&&B(t,i.html),i.style&&H(t,i.style),i.tooltip&&X(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{P(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(!_t.has(e)){_t.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{P(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{_t.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 Dt extends Nt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,L(t,this.$parent),I||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=M(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 c(l({},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}=M(e,t),n=D('[data-value="1"]',t);n&&U(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&U(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 c(l({},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}=M(e,t),n=D('[data-value="default"]',t);n&&U(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(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 c(l({},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}=M(e,t),n=D('[data-value="normal"]',t);n&&U(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>c(l({},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 c(l({},t),{html:`ArtPlayer ${g}`})}({name:"version",index:50})),this.add(function(t){return e=>c(l({},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}=tt(e),{height:c,width:d}=tt(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),H(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{G(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Ft(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 Wt(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)})})}function Yt(t,e){const{$progress:r}=t.template,{left:n}=tt(r),o=ct((I?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 Bt(t,e,r=()=>!0){if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Yt(t,e);t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function jt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=S(e),{on:a}=M(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||Yt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?j(h,"left",0):o>e.clientWidth-a/2?j(h,"left",e.clientWidth-a+"px"):j(h,"left",o-a/2+"px")}r.indicator?B(p,r.indicator):j(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&I;if("loaded"===r&&j(c,"width",100*n+"%"),"hover"===r&&(j(l,"width",100*n+"%"),G(a,u)?function(r){const{width:n}=Yt(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?j(h,"left",0):n>e.clientWidth-i/2?j(h,"left",e.clientWidth-i+"px"):j(h,"left",n-i/2+"px")}(a):f(a),0===n?V(o,"art-progress-hover"):W(o,"art-progress-hover")),"played"===r&&(j(d,"width",100*n+"%"),j(p,"left",100*n+"%")),m){W(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Wt(i,()=>{V(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 Ht(t){return e=>c(l({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{jt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=M(t,e);if(!I){let e=!1;i(r,"click",e=>{e.target!==n&&Bt(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=Yt(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=Yt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function qt(t){const{option:e}=t.art;e.isLive||t.add(Ht({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.play),s=Tt(t,o.pause);function l(){j(a,"display","flex"),j(s,"display","none")}function c(){j(a,"display","none"),j(s,"display","flex")}X(a,i.get("Play")),X(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=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=M(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}=tt(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)j(i,"display","none"),j(a,"display","flex"),j(h,"top","100%"),j(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;j(i,"display","flex"),j(a,"display","none"),j(h,"top",100-t+"%"),j(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}),I)j(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=>c(l({},t),{style:I?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=M(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&&!$(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!I&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=M(e,t),{icons:n}=e;Tt(t,n.screenshot),r(t,"click",()=>{e.screenshot()})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e;Tt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{X(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e;Tt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{X(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=>c(l({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=M(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=>c(l({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenWebOn),s=Tt(t,o.fullscreenWebOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(X(t,i.get("Exit Web Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(X(t,i.get("Web Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=M(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenOn),s=Tt(t,o.fullscreenOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(X(t,i.get("Exit Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(X(t,i.get("Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rXt.get(t).option.selector}),gt(t,"$control_item",{get:()=>Xt.get(t).item}),gt(t,"$control_value",{get:()=>Xt.get(t).value})),Xt.set(t,e)}function Kt(t,e){t.innerHTML=e}function Zt(t,e,r,n,o){const{proxy:i}=t.events,a=S(n),s=r.selector;W(n,"art-control-selector");const l=document.createElement("div");W(l,"art-selector-value"),B(l,r.html),n.textContent="",B(n,l);const c=Tt(n,'
');for(let d=0;dd(null,null,function*(){if(a.closed)return;const o=rt(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 Ut.set(t,e),()=>{Ut.get(t)===e&&Ut.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()&&Kt(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class Jt extends Nt{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;L(t,n);const{on:o}=M(t,n);o("mousemove",()=>{I||(this.show=!0)}),o("click",()=>{I?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=G(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?(V(r,"art-hide-cursor"),W(r,"art-hover"),this.timer=Date.now()):(W(r,"art-hide-cursor"),V(r,"art-hover"))}),this.init(),$(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=S(e),{on:i}=M(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(){qt(this)}add(t){if(E(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){Kt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Qt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(E(t))return;const o=G(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),$(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(E(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),E(t))return;(!I||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),E(t))return;I?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}const te=new WeakMap,ee=new WeakMap,re=new WeakMap;function ne(t){return re.get(t)||$(t)}function oe(t){const e=te.get(t),r=re.get(t);return()=>te.get(t)===e&&(!e||e.active())&&re.get(t)===r&&(!r||!r.closed)}function ie(t){const e=re.get(t),r=$(t).child(),n=r.child();re.set(t,r),r.add(()=>{re.get(t)===r&&re.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!E(t)&&!n.closed&&te.get(t)===o};return te.set(t,o),n.add(()=>{te.get(t)===o&&te.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function ae(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function se(t,e,r){ee.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{ee.get(t)===e&&(ee.delete(t),ae(e))}}function le(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function ce(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!E(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),$(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(E(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:oe(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{Bt(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(E(t))return;const n=(...e)=>{if(!E(t))return r(...e)};t.on(e,n),$(t).add(()=>{t.off(e,n)})}}function ge(t){if(!t.constructor.USE_RAF)return;const e=$(t);let r=()=>{};const n=()=>{E(t)||(t.playing&&t.emit("raf"),E(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:$(e),cleaning:!1})}(this,t),$(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Qt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{E(t)||(W(r,"art-hover"),t.emit("hover",!0,e))},e=>{E(t)||(V(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{E(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(),E(t)||(t.aspectRatio=e,E(t)||(r.show=""))});const s=$(t);let l=()=>{};const c=()=>{E(t)||(l(),l=Wt(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(!I||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=$(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)),E(t)||(s=!0,Wt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;$(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(E(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||E(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||E(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}),I||this.init()}init(){const t=this.art;if(E(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(!E(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=l(l({},Ee),t.option.icons);for(const r in e)gt(this,r,{get:()=>J(r,e[r])})}}class Ce extends Nt{constructor(t){super(t),this.name="info",I||this.init()}init(){const{proxy:t,constructor:e,template:{$infoPanel:r,$infoClose:n,$video:o}}=this.art;t(n,"click",()=>{this.show=!1});let i=()=>{};const a=F("[data-video]",r)||[];this.art.on("destroy",()=>i());const s=$(this.art);!function t(){for(let e=0;e{j(o,"display","none"),j(i,"display",null)}),n.proxy(e.$state,"click",()=>at(t.play()))}}class Me{constructor(t){this.art=t,this.timer=null,$(t).add(()=>this.destroy()),t.on("destroy",()=>this.destroy())}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}set show(t){if($(this.art).closed)return;const{constructor:e,template:{$player:r,$noticeInner:n}}=this.art;t?(n.textContent=t instanceof Error?t.message.trim():t,W(r,"art-notice-show"),clearTimeout(this.timer),this.timer=setTimeout(()=>{n.textContent="",V(r,"art-notice-show")},e.NOTICE_TIME)):V(r,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function ze({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ae(t,e){if(!ze(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 ze(r)?r:void 0}function Oe(t){const{$container:e,$video:r}=t.template;gt(t,"autoHeight",{value(){if(E(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!ze(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||E(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function Re(t,e,r,n=!1){const o=e=>{E(t)||r(e)};t[n?"once":"on"](e,o),$(t).add(()=>{t.off(e,o)})}function Ie(t,e,r){for(const[n,o]of e){if(E(t)||r&&!r())return;t[n].show=o}}function _e(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=ne(t),l=0;return{reset(){l=0,null==a||a.dispose(),V(i,"art-error")},loadStart(){V(i,"art-error")},schedule(c){(c=>d(null,null,function*(){if(E(t))return;const d=ne(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!E(t)&&!u.closed&&d===ne(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Ne(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{E(t)||t.emit(`video:${e.type}`,e)})}(t);const e=_e(t);!function(t,e){Re(t,"video:canplay",()=>{e.reset(),Ie(t,[["loading",!1]])}),Re(t,"video:canplay",()=>{Ie(t,[["loading",!1],["controls",!0],["mask",!0]]),E(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Re(t,"video:ended",()=>{if(e.loop){const e=oe(t);if(t.seek=0,E(t)||!e())return;at(t.play()),e()&&Ie(t,[["controls",!1],["mask",!1]],e)}else Ie(t,[["controls",!0],["mask",!0]])})}(t),Re(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Re(t,"video:loadedmetadata",()=>{t.emit("resize"),I&&Ie(t,[["loading",!1],["controls",!0],["mask",!0]])}),Re(t,"video:loadstart",()=>{e.loadStart(),Ie(t,[["loading",!0],["mask",!1],["controls",!0]])}),Re(t,"video:pause",()=>{Ie(t,[["controls",!0],["mask",!0]])}),Re(t,"video:play",()=>{Ie(t,[["mask",!1]]),E(t)||j(r,"display","none")}),Re(t,"video:playing",()=>Ie(t,[["mask",!1]])),Re(t,"video:progress",()=>{t.playing&&Ie(t,[["loading",!1]])}),Re(t,"video:seeked",()=>Ie(t,[["loading",!1],["mask",!0]])),Re(t,"video:seeking",()=>Ie(t,[["loading",!0],["mask",!1]])),Re(t,"video:timeupdate",()=>Ie(t,[["mask",!1]])),Re(t,"video:waiting",()=>Ie(t,[["loading",!0],["mask",!1]]))}(t,e)}const De=[["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"]],Fe=(()=>{if("undefined"===typeof document)return!1;const t=De[0],e={};for(const r of De){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),We={change:Fe.fullscreenchange,error:Fe.fullscreenerror},Ve={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Ve.off("change",o),r()};Ve.on("change",o);const i=t[Fe.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Ve.isFullscreen)return void t();const r=()=>{Ve.off("change",r),t()};Ve.on("change",r);const n=document[Fe.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Ve.isFullscreen?Ve.exit():Ve.request(t,e),onchange(t){Ve.on("change",t)},onerror(t){Ve.on("error",t)},on(t,e){const r=We[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=We[t];r&&document.removeEventListener(r,e,!1)},raw:Fe};function Ye(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(Ve,{isFullscreen:{get:()=>Boolean(document[Fe.fullscreenElement])},element:{enumerable:!0,get:()=>document[Fe.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Fe.fullscreenEnabled])}});const Be=new WeakMap;function je(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function He(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Be.get(t);if(!n){n=new WeakMap,Be.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),je(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),je(i))}function qe(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&&He(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Ft(i,t.document,t.changeEvent,m),Ft(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=Be.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&&He(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 Ue(t,e){const r=$(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()}),Ft(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=Be.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||E(t))return;s=r;const o=l,a=()=>E(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")))}),Ft(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!E(t)&&t.emit("fullscreenError",r)}),{get:()=>!E(t)&&i(),set(n){if(E(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=qe(e,r,c,()=>{!E(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw E(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const Xe=new WeakSet;function Ge(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Ke(t){Xe.delete(t),t.removeEventListener("webkitbeginfullscreen",Ze),t.removeEventListener("webkitpresentationmodechanged",Ze)}function Ze(t){var e;if(Xe.has(this)&&Ge(this,"webkitbeginfullscreen"===t.type)){Ke(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function Je(t){Xe.add(t),t.addEventListener("webkitbeginfullscreen",Ze),t.addEventListener("webkitpresentationmodechanged",Ze)}function Qe(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=Ge(e),i=o,a=!1,s=0;const l=()=>Ge(e,n);function c(r){if(E(t)||(c=e,Xe.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=()=>E(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&&Je(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Ft(r,e,"webkitbeginfullscreen",()=>c(!0)),Ft(r,e,"webkitendfullscreen",()=>c(!1)),Ft(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!E(t)&&l(),set(r){if(E(t))return;const n=++s;if(i=Boolean(r),r){if(Ke(e),t.state="fullscreen",E(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 tr(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(E(t))return;const i=function(t){const e=Ve.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:()=>Ye(t,e.requestFullscreen,void 0),exit:()=>Ye(r,e.exitFullscreen)}}(o);i?gt(t,"fullscreen",Ue(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?gt(t,"fullscreen",Qe(t)):gt(t,"fullscreen",{get:()=>!1,set(){E(t)||(r.show=e.get("Fullscreen Not Supported"))}}),gt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),$(t).add(()=>{t.off("video:loadedmetadata",i)})}function er(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function rr({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 nr(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()&&(rr(t.placement),r()))}return $(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 y([a,s])}throw a}}),i=>{if(E(t))return;const a=++n,s=()=>a===n&&!E(t);if(i){r||(r={placement:er(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 or(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 ir(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function ar(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),Ft(o,e,"click",n),Ft(o,l,"click",()=>{at(t.play())}),Ft(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=""};Ft(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=or(i.left,i.top,ir(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 sr(t){const{$player:e,$video:r}=t.template,n=$(t).child();let o,i,a=0,s=!1,d=!1;const u=()=>!E(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{rr(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(E(t))return;const r=++a;d=!1,p(),E(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(E(t))return;const m=++a;if(s)d=!0;else if(t.state="mini",!E(t)&&m===a){null!=i||(i=er(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=ar(t,n,u,h)}finally{s=!1}}if(d)return d=!1,void f();if(!o||E(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),E(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}:c(l({},or(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,ir(o.element));if(E(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),E(t)||m!==a)return;t.storage.set("left",i.left)}E(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,E(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 lr=new WeakSet,cr=t=>"picture-in-picture"===t.webkitPresentationMode;function dr(t){lr.delete(t),t.removeEventListener("webkitpresentationmodechanged",ur),t.removeEventListener("enterpictureinpicture",ur)}function ur(){var t;if(lr.has(this)&&cr(this)){dr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function pr(t){lr.add(t),t.addEventListener("webkitpresentationmodechanged",ur),t.addEventListener("enterpictureinpicture",ur)}function hr(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=$(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||!E(t)&&a||d()},e=>{E(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Ft(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!E(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Ft(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!E(t)&&o()?e:null,set(n){if(E(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",E(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=$(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(E(t)||lr.has(e))return;const s=cr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),E(t)||i!==l||cr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&pr(e),cr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Ft(r,e,l,()=>s());return{get:()=>!E(t)&&cr(e),set(r){var n;if(E(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(dr(e),t.state="pip",E(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,pr(e)),cr(e)&&e.webkitSetPresentationMode("inline");E(t)||l!==i||c!==a||cr(e)!==Boolean(r)||s(!0)}}}(t)):gt(t,"pip",{get:()=>!1,set(){E(t)||(r.show=e.get("PIP Not Supported"))}})}function fr(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 d(this,null,function*(){const r=function(t){return t&&Ut.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!E(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!E(t)&&r()&&(n.show=i)}return e.html})}})}})}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(E(t)||e===t.url)return void n();const i=ie(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(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child(),h={"video:error":u,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){u(e)}},"video:canplay":()=>{if(!c())return;p.dispose();d(null,null,function*(){if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{yield t.play()}catch(e){}c()&&(t.notice.show="",l())}}).catch(u)}},f=a.child(),m=[],g=Object.keys(h);for(const e of g)mr(f,t,e,t=>{i.acceptingEvents&&m.push([e,t])},!1);if(se(t,i,e),!c())return;if(t.notice.show="",!c())return;const v=()=>{if(f.dispose(),!e)return void l();const r={};for(const e of g)r[e]=mr(p,t,e,h[e]);for(const[t,e]of m){if(!c()||p.closed)break;r[t](e)}m.length=0};i.assigned?v():i.onAssigned=v}catch(p){u(p)}})}function vr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",(o,s,l)=>d(null,null,function*(){var c;const d=null==(c=t.controls)?void 0:c.thumbnails,{url:u,scale:p}=e.thumbnails;if(!d||!u)return;if("hover"===o||"played"===o&&l&&I){if(a||i||(i=!0,a=yield et(u,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-h/2?j(s,"left",r.clientWidth-h+"px"):j(s,"left",o-h/2+"px")}(o)}})),gt(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function yr(t){const{option:e,template:{$video:r}}=t;gt(t,"url",{get:()=>r.src,set(n){return d(this,null,function*(){if(E(t))return;const o=function(t){const e=ee.get(t);return ee.delete(t),e||ie(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=>le(o,t))}else{if(i&&URL.revokeObjectURL(i),!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){le(o,i)}finally{ae(o)}})}})}class br{constructor(t){yr(t),function(t){const{template:{$video:e}}=t;gt(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;gt(t,"play",{value(){return d(this,null,function*(){const a=oe(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()})}(t),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}})}(t),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)}})}(t),function(t){const{$video:e}=t.template;gt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=ct(n,0,t.duration))}})}(t),function(t){gt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),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})}(t),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}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;gt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!E(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=Ae({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(E(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}`,E(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=Z("canvas");gt(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),gt(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),gt(t,"screenshot",{value:e=>d(null,null,function*(){const n=yield t.getDataURL();return lt(n,`${e||`artplayer_${ut(r.currentTime)}`}.png`),t.emit("screenshot",n),n})})}(t),tr(t),nr(t),hr(t),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})}(t),function(t){gt(t,"played",{get:()=>t.currentTime/t.duration})}(t),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)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;gt(t,"autoSize",{value(){if(E(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!ze(o))return;const i=tt(e),a=Ae(i,o.width/o.height);a&&!E(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}))}})}(t),function(t){const e=t;gt(t,"rect",{get:()=>tt(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})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;gt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){E(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,E(t)||t.emit("flip",o))}})}(t),function(t){gt(t,"mini",sr(t))}(t),function(t){const{template:{$poster:e}}=t;gt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){j(e,"backgroundImage",`url(${t})`)}})}(t),Oe(t),function(t){const{$player:e}=t.template;gt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){gt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){gt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),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{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,gt(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),fr(t),vr(t),Ne(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=ct(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=ct(i,0,1)),e.poster&&j(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(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 ze(t)&&ze(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=$(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,E(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=nt();if(E(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;E(t)||(r?o?s(!1):e()&&(i(),i=Wt(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 $(t).add(o),i=>{var a,s;if(E(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=()=>!E(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),$(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Cr(t){const{i18n:e,icons:r,storage:n,constructor:o,proxy:i,template:{$poster:a}}=t,s=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '}),l=D(".art-auto-playback-last",s),c=D(".art-auto-playback-jump",s),d=D(".art-auto-playback-close",s);B(d,r.close);let u=null;function p(){const r=(n.get("times")||{})[t.option.id||t.option.url];clearTimeout(u),j(s,"display","none"),r&&r>=o.AUTO_PLAYBACK_MIN&&(j(s,"display","flex"),l.textContent=`${e.get("Last Seen")} ${ut(r)}`,c.textContent=e.get("Jump Play"),i(d,"click",()=>{j(s,"display","none")}),i(c,"click",()=>{t.seek=r,at(t.play()),j(a,"display","none"),j(s,"display","none")}),t.once("video:timeupdate",()=>{u=setTimeout(()=>{j(s,"display","none")},o.AUTO_PLAYBACK_TIMEOUT)}))}return t.on("video:timeupdate",()=>{if(t.playing){const e=n.get("times")||{},r=Object.keys(e);r.length>o.AUTO_PLAYBACK_MAX&&delete e[r[0]],e[t.option.id||t.option.url]=t.currentTime,n.set("times",e)}}),t.on("ready",p),t.on("restart",p),{name:"auto-playback",get times(){return n.get("times")||{}},clear:()=>n.del("times"),delete(t){const e=n.get("times")||{};return delete e[t],n.set("times",e),e}}}function Lr(t){const{constructor:e,proxy:r,template:{$player:n,$video:o}}=t;let i=null,a=!1,s=1;const l=()=>{clearTimeout(i),a&&(a=!1,t.playbackRate=s,V(n,"art-fast-forward"))};return r(o,"touchstart",r=>{1===r.touches.length&&t.playing&&!t.isLock&&(i=setTimeout(()=>{a=!0,s=t.playbackRate,t.playbackRate=e.FAST_FORWARD_VALUE,W(n,"art-fast-forward")},e.FAST_FORWARD_TIME))}),t.on("document:touchmove",l),t.on("document:touchend",l),{name:"fastForward",get state(){return Y(n,"art-fast-forward")}}}function Sr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return Y(n,"art-lock")}function i(){W(n,"art-lock"),t.isLock=!0,t.emit("lock",!0)}function a(){V(n,"art-lock"),t.isLock=!1,t.emit("lock",!1)}return e.add({name:"lock",mounted(e){const n=B(e,r.lock),o=B(e,r.unlock);j(n,"display","none"),t.on("lock",t=>{t?(j(n,"display","inline-flex"),j(o,"display","none")):(j(n,"display","none"),j(o,"display","inline-flex"))})},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function Pr(t){return t.on("control",e=>{e?V(t.template.$player,"art-mini-progress-bar"):W(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Mr{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){E(t.art)||!e.miniProgressBar||e.isLive||t.add(Pr),!E(t.art)&&e.lock&&I&&t.add(Sr),E(t.art)||!e.autoPlayback||e.isLive||t.add(Cr),!E(t.art)&&e.autoOrientation&&I&&t.add(Tr),!E(t.art)&&e.fastForward&&I&&!e.isLive&&t.add(Lr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!E(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(E(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(E(t.art))return t;let o=n;const i=yt(t,o);if(E(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return E(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),E(t.art)||gt(t,o,{value:r})),t}(this,t,e)}}const zr=new WeakMap;function Ar(t){return!t.closed&&!zr.get(t)}function Or(t){zr.set(t,(zr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(zr.get(t)||1)-1;r?zr.set(t,r):zr.delete(t)}}const Rr=new WeakMap,Ir=new WeakMap,_r=["$parent","$parents","$option","$events","$formatted"];function Nr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Rr.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=Rr.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function Dr(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 Fr(t){const e=Rr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Wr(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>Ur(t,o)])try{e()}catch(d){d instanceof y?l.push(...d.errors):l.push(d)}if(r.closed||E(t)||(o.push(...i.splice(0)),qr.set(r,o),jr.set(e,r),Hr.set(e,n)),a(),l.length)throw new y(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function Jr(t,e,r,n,o,i){const a=i||Gr(e);if(!Ar(a)||E(t))return;const s=t.proxy(r,n,e=>{if(Ar(a)&&!E(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Ar(a)||E(t)?t.events.remove(s):(Fr(e).events.push(s),i&&i!==jr.get(e)&&i.add(()=>{const r=Fr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Qr(t,e,r,n){const o=Gr(e);if(!Ar(o)||E(t))return;const i=(...e)=>{if(Ar(o)&&!E(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function tn(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||I||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const en=new WeakMap;function rn(t){en.delete(t)}const nn=new WeakMap;function on(t,e){e?nn.set(t,e):nn.delete(t)}function an(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=nn.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(),on(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 sn=new WeakMap;function ln(t,e,r,n,o,i,a,s){return d(this,null,function*(){try{const l=Gr(e),c=Gr(i),d=(sn.get(i)||0)+1;sn.set(i,d);const u=()=>Ar(l)&&Ar(c)&&!E(t.art)&&sn.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 cn(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 dn=new WeakMap;function un(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof y?e.push(...r.errors):e.push(r)}if(e.length)throw new y(e)}function pn(t){var e;null==(e=dn.get(t))||e()}function hn(t,e){const r=t.find(e.name);if(E(t.art))return r||e;if(!r)return t.add(e);rn(r),pn(r);const n=an(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?cn(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=Zr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Or(Yr(t)))}catch(l){try{un([...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,un([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,un([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Br(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)dn.get(t)===h&&dn.delete(t);if(E(t.art))return void d.dispose();const e=r.$item;try{un([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)&&U(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&&!E(t.art)&&dn.get(r)===h;for(const v of d.items)dn.set(v,h);const m=$(t.art).add(()=>{u=!1;for(const t of d.items)dn.get(t)===h&&dn.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)dn.get(t)===h&&dn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const fn=new WeakMap;function mn(t,e,r){gt(t,`$${e}`,{configurable:!0,get:()=>r}),gt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",B(r,t)}})}function gn(t,e,r=!1){var n,o;const i=function(t){const e=dn.get(t);return()=>!e||dn.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=$(t)){const n=jr.get(e);(!n||Ar(n)||n.closed)&&Kr(t,e);const o=r.child();return jr.set(e,o),Hr.set(e,r),qr.set(o,Fr(e).events),o.add(()=>{Ur(t,qr.get(o))}),o}(t.art,e,Yr(a)),p=()=>Ar(u)&&!E(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(on(e),W(h,"art-setting-item"),j(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=B(h,'
'),f=B(h,'
'),m=document.createElement("div");switch(W(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;B(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;B(m,t)}else B(m,c.check)}if(B(i,m),!p())return;mn(e,"icon",m);const g=document.createElement("div");W(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;B(g,v),B(i,g),mn(e,"html",g);const y=document.createElement("div");W(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(B(y,b),B(f,y),mn(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");W(t,"art-setting-item-right-icon");const r=B(t,c.switchOn),n=B(t,c.switchOff),o=e.switch;if(!p())return;j(o?n:r,"display","none"),B(f,t),gt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;on(e,()=>{const t=i;return()=>{i=t}}),gt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(j(n,"display","none"),j(r,"display",null)):(j(n,"display",null),j(r,"display","none"))}});break}case"range":{const t=document.createElement("div");W(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",B(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))}W(r,"art-setting-range"),B(f,t),gt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;on(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");W(t,"art-setting-item-right-icon"),B(t,c.arrowRight),B(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=Gr(e),a=(t,r,n)=>Jr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>ln(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=>ln(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 ln(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&W(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>ln(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):B(a,h),e.mounted&&p()&&Wt(u,()=>{var r;if(!E(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 vn(t,e=t.option){var r;if(E(t.art))return;const n=t.cache.get(e);if(n&&!Ar(Yr(n)))return;const o=(fn.get(t)||0)+1;fn.set(t,o);const i=()=>fn.get(t)===o&&!E(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)&&U(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{U(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Yr(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=$(t.art).child();return Vr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!E(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;W(n,"art-setting-panel"),B(t.$parent,n),U(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Ir.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=$(e).child(),n=(t,n)=>{if(r.closed||E(e))return;const o=(...t)=>{if(!r.closed&&!E(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=G(r,e.controls.setting),o=G(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||E(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(),Qr(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(),Qr(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(),Qr(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)=>{Qr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Wr(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&&U(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=Ir.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;oFr(t).parent},$parents:{get:()=>Fr(t).parents},$option:{get:()=>Fr(t).option},$events:{get:()=>Fr(t).events},$formatted:{get:()=>!0}}),Rr.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 Wr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){tn(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&&Br(n)}catch(i){r.push(i)}}try{Kr(t.art,e)}catch(i){i instanceof y?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new y(r)}(this,t)}remove(t){const e=this.find(t);it(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{rn(t),pn(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 y?o.push(...i.errors):o.push(i)}if(o.length)throw new y(o)}update(t){return hn(this,t)}add(t,e=this.option){var r;if(E(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={};en.set(t,e);const r=()=>en.get(t)===e;return{current:r,finish(){r()&&en.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(E(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");j(i,"height",`${o}px`),W(i,"art-setting-item"),W(i,"art-setting-item-back");const a=B(i,'
'),s=document.createElement("div");W(s,"art-setting-item-left-icon"),B(s,n),B(a,s),B(a,e.$parent.html),Jr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Yr(r)),B(r,i)}(this,t)}createItem(t,e=!1){gn(this,t,e)}render(t=this.option){vn(this,t)}}class wn{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 xn='.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 kn{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 d(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const $n=new WeakMap;function En(t){return $n.get(t)}function Tn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const Cn=Nt;class Ln extends Cn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=$(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return $n.set(t,n),r.add(()=>{Tn(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?H(r,t):j(r,t,e)}update(){!function(t){const e=En(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 d(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=c(l(l({},o.subtitle),e),{url:t}),a=En(this),s=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=En(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&&Tn(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 d(this,null,function*(){const e=En(this),r=function(t){const e=t.request,r=new kn(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(()=>d(this,null,function*(){if(!this.textTrack)return null;if(m(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 Sn=`\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
${g}
\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 Pn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=D(e.container),it(this.$container,`No container element found by ${e.container}`)),it(Q(),"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=x.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=k(t);o.rollback=r,x.set(e,t),o.releaseContainer=()=>{x.get(e)===t&&x.delete(e)}}(t,this.$container,cn(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return Sn}query(t){return D(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Pn.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);!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),K(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&W(this.$player,"art-backdrop"),I&&W(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":W(this.$player,"art-destroy")}}const Mn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class zn{on(t,e,r){const n=this.e||(this.e={});let o=Mn(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=(Mn(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=Mn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;ie.call(this,this)),Rn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Rn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=k(t);return e.rollback=void 0,!e.scope.closed})(this)&&On.push(this)}catch(n){try{T(this,On,!0,Rn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(o){console.warn("Failed to clean up ArtPlayer initialization:",o)}throw n}}static get instances(){return On}static get version(){return g}static get config(){return v}static get utils(){return Et}static get scheme(){return It}static get Emitter(){return zn}static get validator(){return m}static get kindOf(){return m.kindOf}static get html(){return Pn.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:A?"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){T(this,On,t,Rn.REMOVE_SRC_WHEN_DESTROY)}}return Rn.STYLE=xn,Rn.DEBUG=!1,Rn.CONTEXTMENU=!0,Rn.NOTICE_TIME=2e3,Rn.SETTING_WIDTH=250,Rn.SETTING_ITEM_WIDTH=200,Rn.SETTING_ITEM_HEIGHT=35,Rn.RESIZE_TIME=200,Rn.SCROLL_TIME=200,Rn.SCROLL_GAP=50,Rn.AUTO_PLAYBACK_MAX=10,Rn.AUTO_PLAYBACK_MIN=5,Rn.AUTO_PLAYBACK_TIMEOUT=3e3,Rn.RECONNECT_TIME_MAX=5,Rn.RECONNECT_SLEEP_TIME=1e3,Rn.CONTROL_HIDE_TIME=3e3,Rn.DBCLICK_TIME=300,Rn.DBCLICK_FULLSCREEN=!0,Rn.MOBILE_DBCLICK_PLAY=!0,Rn.MOBILE_CLICK_PLAY=!1,Rn.AUTO_ORIENTATION_TIME=200,Rn.INFO_LOOP_TIME=1e3,Rn.FAST_FORWARD_VALUE=3,Rn.FAST_FORWARD_TIME=1e3,Rn.TOUCH_MOVE_RATIO=.5,Rn.VOLUME_STEP=.1,Rn.SEEK_STEP=5,Rn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Rn.ASPECT_RATIO=["default","4:3","16:9"],Rn.FLIP=["normal","horizontal","vertical"],Rn.FULLSCREEN_WEB_IN_BODY=!0,Rn.LOG_VERSION=!0,Rn.USE_RAF=!1,Rn.REMOVE_SRC_WHEN_DESTROY=!0,_&&(window.Artplayer=Rn,N("artplayer-style",xn),setTimeout(()=>{Rn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Rn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Rn}); diff --git a/packages/artplayer/dist/artplayer.mjs b/packages/artplayer/dist/artplayer.mjs index cf92ebd7c..d64a25074 100644 --- a/packages/artplayer/dist/artplayer.mjs +++ b/packages/artplayer/dist/artplayer.mjs @@ -361,29 +361,29 @@ class ResourceScope { throw new ResourceCleanupError(errors); } } -const states$2 = /* @__PURE__ */ new WeakMap(); +const states$4 = /* @__PURE__ */ new WeakMap(); const containers = /* @__PURE__ */ new WeakMap(); function beginLifecycle(owner) { - states$2.set(owner, { scope: new ResourceScope(), destroying: false }); + states$4.set(owner, { scope: new ResourceScope(), destroying: false }); } -function stateOf(owner) { - const state2 = states$2.get(owner); +function stateOf$1(owner) { + const state2 = states$4.get(owner); if (!state2) throw new Error("ArtPlayer lifecycle has not been initialized"); return state2; } function getScope(owner) { - return stateOf(owner).scope; + return stateOf$1(owner).scope; } function isClosing(owner) { - const state2 = stateOf(owner); + const state2 = stateOf$1(owner); return state2.destroying || state2.scope.closed; } function ownContainer(owner, container, rollback) { const current2 = containers.get(container); if (current2 && current2 !== owner) throw new Error("Cannot mount multiple instances on the same dom element"); - const state2 = stateOf(owner); + const state2 = stateOf$1(owner); state2.rollback = rollback; containers.set(container, owner); state2.releaseContainer = () => { @@ -392,12 +392,12 @@ function ownContainer(owner, container, rollback) { }; } function finishLifecycle(owner) { - const state2 = stateOf(owner); + const state2 = stateOf$1(owner); state2.rollback = void 0; return !state2.scope.closed; } function destroyInstance(owner, instances2, removeHtml, removeSource, failed = false) { - const state2 = stateOf(owner); + const state2 = stateOf$1(owner); if (state2.destroying || state2.scope.closed) return; state2.destroying = true; @@ -432,20 +432,20 @@ function destroyInstance(owner, instances2, removeHtml, removeSource, failed = f if (errors.length) throw errors[0]; } -const scopes$3 = /* @__PURE__ */ new WeakMap(); +const scopes$2 = /* @__PURE__ */ new WeakMap(); function ownEntry(art, element) { const scope = getScope(art).child(); - scopes$3.set(element, scope); + scopes$2.set(element, scope); return scope; } function entryScope(element) { - const scope = scopes$3.get(element); + const scope = scopes$2.get(element); if (!scope) throw new Error("ArtPlayer component has not been registered"); return scope; } function releaseEntry(element) { - scopes$3.get(element)?.dispose(); + scopes$2.get(element)?.dispose(); } function proxyEntry(art, element, target, name, callback) { const scope = entryScope(element); @@ -1620,16 +1620,18 @@ function getPosFromEvent(art, event) { const percentage = clamp(width / $progress.clientWidth, 0, 1); return { second, time: time2, width, percentage }; } -function setCurrentTime(art, event) { +function setCurrentTime(art, event, active2 = () => true) { if (art.isRotate) { const percentage = (event.touches[0].clientY - art.top) / art.height; const second = percentage * art.duration; art.emit("setBar", "played", percentage, event); - art.seek = second; + if (active2()) + art.seek = second; } else { const { second, percentage } = getPosFromEvent(art, event); art.emit("setBar", "played", percentage, event); - art.seek = second; + if (active2()) + art.seek = second; } } function installProgressInteractions(art, $control) { @@ -2213,26 +2215,30 @@ class Control extends Component { renderSelector(this.art, (target) => this.check(target), option, $ref, events); } } -function clickInit(art, events) { - const { - constructor, - template: { $player, $video } - } = art; - function onDocumentClick(event) { - if (includeFromEvent(event, $player)) { - art.isInput = event.target.tagName === "INPUT"; - art.isFocus = true; - art.emit("focus", event); - } else { - art.isInput = false; - art.isFocus = false; - art.emit("blur", event); - } - } +function pointerFocus(art) { + const { $player } = art.template; + const onDocumentClick = (event) => { + if (isClosing(art)) + return; + const inside = includeFromEvent(event, $player); + art.isInput = inside && event.target?.tagName === "INPUT"; + art.isFocus = inside; + art.emit(inside ? "focus" : "blur", event); + }; art.on("document:click", onDocumentClick); art.on("document:contextmenu", onDocumentClick); + getScope(art).add(() => { + art.off("document:click", onDocumentClick); + art.off("document:contextmenu", onDocumentClick); + }); +} +function clickInit(art, events) { + const { constructor, template: { $video } } = art; + pointerFocus(art); let clickTimes = []; events.proxy($video, "click", (event) => { + if (isClosing(art)) + return; const now = Date.now(); clickTimes.push(now); const { MOBILE_CLICK_PLAY, DBCLICK_TIME, MOBILE_DBCLICK_PLAY, DBCLICK_FULLSCREEN } = constructor; @@ -2240,25 +2246,21 @@ function clickInit(art, events) { switch (clicks.length) { case 1: art.emit("click", event); - if (isMobile) { - if (!art.isLock && MOBILE_CLICK_PLAY) { - silencePromise(art.toggle()); - } - } else { + if (isClosing(art)) + return; + if (!isMobile || !art.isLock && MOBILE_CLICK_PLAY) silencePromise(art.toggle()); - } clickTimes = clicks; break; case 2: art.emit("dblclick", event); + if (isClosing(art)) + return; if (isMobile) { - if (!art.isLock && MOBILE_DBCLICK_PLAY) { + if (!art.isLock && MOBILE_DBCLICK_PLAY) silencePromise(art.toggle()); - } - } else { - if (DBCLICK_FULLSCREEN) { - art.fullscreen = !art.fullscreen; - } + } else if (DBCLICK_FULLSCREEN) { + art.fullscreen = !art.fullscreen; } clickTimes = []; break; @@ -2267,131 +2269,251 @@ function clickInit(art, events) { } }); } -function GetSlideAngle(dx, dy) { - return Math.atan2(dy, dx) * 180 / Math.PI; +const current = /* @__PURE__ */ new WeakMap(); +const assignments = /* @__PURE__ */ new WeakMap(); +const sources = /* @__PURE__ */ new WeakMap(); +function getSourceScope(owner) { + return sources.get(owner) || getScope(owner); } -function GetSlideDirection(startX, startY, endX, endY) { +function captureSource(owner) { + const operation = current.get(owner); + const source = sources.get(owner); + return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed); +} +function beginSource(owner) { + const previous = sources.get(owner); + const source = getScope(owner).child(); + const scope = source.child(); + sources.set(owner, source); + source.add(() => { + if (sources.get(owner) === source) + sources.delete(owner); + }); + const operation = { + scope, + assigned: false, + acceptingEvents: false, + active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation + }; + current.set(owner, operation); + scope.add(() => { + if (current.get(owner) === operation) + current.delete(owner); + operation.onAssigned = void 0; + operation.onError = void 0; + }); + previous?.dispose(); + return operation; +} +function takeAssignment(owner) { + const operation = assignments.get(owner); + assignments.delete(owner); + return operation || beginSource(owner); +} +function finishAssignment(operation) { + operation.assigned = true; + const callback = operation.onAssigned; + operation.onAssigned = void 0; + if (operation.active()) + callback?.(); +} +function assignUrl(owner, operation, url) { + assignments.set(owner, operation); + operation.acceptingEvents = true; + try { + owner.url = url; + } finally { + if (assignments.get(owner) === operation) { + assignments.delete(owner); + finishAssignment(operation); + } + } +} +function failSource(operation, error2) { + if (!operation.active()) + return; + if (operation.onError) + operation.onError(error2); + else + console.warn("Failed to initialize ArtPlayer source:", error2); + operation.scope.dispose(); +} +function slideDirection(startX, startY, endX, endY) { const dy = startY - endY; const dx = endX - startX; - let result = 0; - if (Math.abs(dx) < 2 && Math.abs(dy) < 2) { - return result; - } - const angle = GetSlideAngle(dx, dy); - if (angle >= -45 && angle < 45) { - result = 4; - } else if (angle >= 45 && angle < 135) { - result = 1; - } else if (angle >= -135 && angle < -45) { - result = 2; - } else if (angle >= 135 && angle <= 180 || angle >= -180 && angle < -135) { - result = 3; - } - return result; + if (Math.abs(dx) < 2 && Math.abs(dy) < 2) + return 0; + const angle = Math.atan2(dy, dx) * 180 / Math.PI; + if (angle >= -45 && angle < 45) + return 4; + if (angle >= 45 && angle < 135) + return 1; + if (angle >= -135 && angle < -45) + return 2; + if (angle >= 135 && angle <= 180 || angle >= -180 && angle < -135) + return 3; + return 0; +} +function gestureController(art) { + let drag; + const cancel = () => { + drag = void 0; + }; + const active2 = (current2) => drag === current2 && !isClosing(art) && !art.isLock && !art.option.isLive && art.isRotate === current2.rotated && current2.sourceActive(); + const onLock = (locked) => { + if (locked) + cancel(); + }; + art.on("document:touchend", cancel); + art.on("document:touchcancel", cancel); + art.on("lock", onLock); + getScope(art).add(() => { + cancel(); + art.off("document:touchend", cancel); + art.off("document:touchcancel", cancel); + art.off("lock", onLock); + }); + const start = (target, event) => { + cancel(); + const touch = event.touches[0]; + if (isClosing(art) || art.isLock || art.option.isLive || event.touches.length !== 1 || !touch) + return; + if (![touch.pageX, touch.pageY, touch.clientX, touch.clientY, art.currentTime].every(Number.isFinite)) + return; + const current2 = { + target, + identifier: touch.identifier, + x: touch.pageX, + y: touch.pageY, + time: art.currentTime, + rotated: art.isRotate, + sourceActive: captureSource(art) + }; + drag = current2; + if (target === art.template.$progress) { + const size = art.isRotate ? art.height : art.template.$progress.clientWidth; + if (!Number.isFinite(size) || size <= 0 || !Number.isFinite(art.duration) || art.duration <= 0) { + cancel(); + return; + } + try { + setCurrentTime(art, event, () => active2(current2)); + } catch (error2) { + if (drag === current2) + cancel(); + throw error2; + } + if (active2(current2)) + current2.time = art.currentTime; + } + }; + const move = (event) => { + const current2 = drag; + const touch = event.touches[0]; + if (!current2) + return; + if (!active2(current2) || event.touches.length !== 1 || !touch || touch.identifier !== current2.identifier) { + cancel(); + return; + } + const size = current2.rotated ? art.height : art.width; + const multiplier = current2.target === art.template.$video ? art.constructor.TOUCH_MOVE_RATIO : 1; + if (![touch.pageX, touch.pageY, size, art.duration, multiplier].every(Number.isFinite) || size <= 0 || art.duration <= 0) { + cancel(); + return; + } + const direction = slideDirection(current2.x, current2.y, touch.pageX, touch.pageY); + if (!(current2.rotated ? direction === 1 || direction === 2 : direction === 3 || direction === 4)) + return; + const distance = current2.rotated ? touch.pageY - current2.y : touch.pageX - current2.x; + const ratio = clamp(distance / size, -1, 1); + const time2 = clamp(current2.time + art.duration * ratio * multiplier, 0, art.duration); + art.seek = time2; + if (!active2(current2)) + return; + art.emit("setBar", "played", clamp(time2 / art.duration, 0, 1), event); + if (active2(current2)) + art.notice.show = `${secondToTime(time2)} / ${secondToTime(art.duration)}`; + }; + return { start, move, cancel }; } function gestureInit(art, events) { - if (isMobile && !art.option.isLive) { - const { $video, $progress } = art.template; - let touchTarget = null; - let isDragging = false; - let startX = 0; - let startY = 0; - let startTime = 0; - const onTouchStart = (event) => { - if (event.touches.length === 1 && !art.isLock) { - if (touchTarget === $progress) { - setCurrentTime(art, event); - } - isDragging = true; - const { pageX, pageY } = event.touches[0]; - startX = pageX; - startY = pageY; - startTime = art.currentTime; - } - }; - const onTouchMove = (event) => { - if (event.touches.length === 1 && isDragging && art.duration) { - const { pageX, pageY } = event.touches[0]; - const direction = GetSlideDirection(startX, startY, pageX, pageY); - const isHorizontal = [3, 4].includes(direction); - const isVertical = [1, 2].includes(direction); - const isLegal = isHorizontal && !art.isRotate || isVertical && art.isRotate; - if (isLegal) { - const ratioX = clamp((pageX - startX) / art.width, -1, 1); - const ratioY = clamp((pageY - startY) / art.height, -1, 1); - const ratio = art.isRotate ? ratioY : ratioX; - const TOUCH_MOVE_RATIO = touchTarget === $video ? art.constructor.TOUCH_MOVE_RATIO : 1; - const currentTime = clamp(startTime + art.duration * ratio * TOUCH_MOVE_RATIO, 0, art.duration); - art.seek = currentTime; - art.emit("setBar", "played", clamp(currentTime / art.duration, 0, 1), event); - art.notice.show = `${secondToTime(currentTime)} / ${secondToTime(art.duration)}`; - } - } - }; - const onTouchEnd = () => { - if (isDragging) { - startX = 0; - startY = 0; - startTime = 0; - isDragging = false; - touchTarget = null; - } - }; - if (art.option.gesture) { - events.proxy($video, "touchstart", (event) => { - touchTarget = $video; - onTouchStart(event); - }); - events.proxy($video, "touchmove", onTouchMove); - } - events.proxy($progress, "touchstart", (event) => { - touchTarget = $progress; - onTouchStart(event); - }); - events.proxy($progress, "touchmove", onTouchMove); - art.on("document:touchend", onTouchEnd); - } + if (!isMobile || art.option.isLive) + return; + const { $video, $progress } = art.template; + const gesture = gestureController(art); + const bind2 = (target) => { + events.proxy(target, "touchstart", (event) => gesture.start(target, event)); + events.proxy(target, "touchmove", (event) => gesture.move(event)); + events.proxy(target, "touchcancel", gesture.cancel); + }; + if (art.option.gesture) + bind2($video); + bind2($progress); } +const documentEvents = [ + "click", + "mouseup", + "keydown", + "touchend", + "touchcancel", + "touchmove", + "mousemove", + "pointerup", + "contextmenu", + "pointermove", + "visibilitychange", + "webkitfullscreenchange" +]; +const windowEvents = ["resize", "scroll", "orientationchange"]; function globalInit(art, events) { - const documentEvents = [ - "click", - "mouseup", - "keydown", - "touchend", - "touchmove", - "mousemove", - "pointerup", - "contextmenu", - "pointermove", - "visibilitychange", - "webkitfullscreenchange" - ]; - const windowEvents = [ - "resize", - "scroll", - "orientationchange" - ]; - const destroyEvents = []; - function bindGlobalEvents(source = {}) { - for (let index = 0; index < destroyEvents.length; index++) { - events.remove(destroyEvents[index]); + let active2; + let generation = 0; + getScope(art).add(() => { + active2 = void 0; + generation++; + return void 0; + }); + const release = (binding) => { + if (binding) { + for (const dispose of binding.disposers) + events.remove(dispose); + binding.disposers.length = 0; } - destroyEvents.length = 0; - const { $player } = art.template; - documentEvents.forEach((name) => { + }; + function bindGlobalEvents(source = {}) { + if (isClosing(art)) + return; + const current2 = ++generation; + const binding = { disposers: [] }; + const cancelled = () => current2 !== generation || isClosing(art); + try { + const { $player } = art.template; const doc = source.document || $player.ownerDocument || document; - const destroy = events.proxy(doc, name, (event) => { - art.emit(`document:${name}`, event); - }); - destroyEvents.push(destroy); - }); - windowEvents.forEach((name) => { const win = source.window || $player.ownerDocument?.defaultView || window; - const destroy = events.proxy(win, name, (event) => { - art.emit(`window:${name}`, event); - }); - destroyEvents.push(destroy); - }); + const register = (target, names, prefix) => { + for (const name of names) { + if (cancelled()) + return; + binding.disposers.push(events.proxy(target, name, (event) => { + if (active2 === binding && !isClosing(art)) + art.emit(`${prefix}:${name}`, event); + })); + } + }; + register(doc, documentEvents, "document"); + register(win, windowEvents, "window"); + } catch (error2) { + release(binding); + throw error2; + } + if (cancelled()) { + release(binding); + return; + } + const previous = active2; + active2 = binding; + release(previous); } bindGlobalEvents(); events.bindGlobalEvents = bindGlobalEvents; @@ -2401,85 +2523,229 @@ function hoverInit(art, events) { events.hover( $player, (event) => { + if (isClosing(art)) + return; addClass($player, "art-hover"); art.emit("hover", true, event); }, (event) => { + if (isClosing(art)) + return; removeClass($player, "art-hover"); art.emit("hover", false, event); } ); } +const states$3 = /* @__PURE__ */ new WeakMap(); +function ownListeners(registry, art) { + states$3.set(registry, { scope: getScope(art), cleaning: false }); +} +function stateOf(registry) { + const state2 = states$3.get(registry); + if (!state2) + throw new Error("ArtPlayer event registry has not been initialized"); + return state2; +} +function proxyListener(registry, target, names, callback, option = {}) { + if (Array.isArray(names)) { + const created = []; + try { + return names.map((name2) => { + const dispose2 = proxyListener(registry, target, name2, callback, option); + created.push(dispose2); + return dispose2; + }); + } catch (error2) { + for (const dispose2 of created.reverse()) { + try { + dispose2(); + } catch (cleanupError) { + console.warn("Failed to roll back event listener:", cleanupError); + } + } + throw error2; + } + } + const name = names; + const state2 = stateOf(registry); + if (state2.scope.closed || state2.cleaning) + return () => { + }; + const options = typeof option === "boolean" ? option : { + capture: Boolean(option?.capture), + once: Boolean(option?.once), + passive: option?.passive, + signal: option?.signal + }; + const capture = typeof options === "boolean" ? options : options.capture; + const signal = typeof options === "boolean" ? void 0 : options.signal; + if (state2.scope.closed || state2.cleaning || signal?.aborted) + return () => { + }; + let active2 = true; + function clean(force = false) { + if (!active2 && !force) + return; + target.removeEventListener(name, callback, capture); + signal?.removeEventListener("abort", dispose); + active2 = false; + registry.destroyEvents.delete(dispose); + } + function dispose() { + clean(); + } + registry.destroyEvents.add(dispose); + try { + target.addEventListener(name, callback, options); + if (!active2 || state2.scope.closed || state2.cleaning) + clean(true); + else if (signal?.aborted) + dispose(); + else + signal?.addEventListener("abort", dispose, { once: true }); + } catch (error2) { + try { + clean(true); + } catch (cleanupError) { + console.warn("Failed to roll back event listener:", cleanupError); + } + throw error2; + } + return dispose; +} +function removeListener(registry, dispose) { + if (!registry.destroyEvents.has(dispose)) + return; + try { + dispose(); + registry.destroyEvents.delete(dispose); + } catch (error2) { + console.warn("Failed to remove event listener:", error2); + } +} +function destroyListeners(registry) { + const state2 = stateOf(registry); + if (state2.cleaning) + return; + state2.cleaning = true; + try { + for (const dispose of registry.destroyEvents) { + try { + dispose(); + registry.destroyEvents.delete(dispose); + } catch (error2) { + console.warn("Failed to destroy event listener:", error2); + } + } + } finally { + state2.cleaning = false; + } +} function moveInit(art, events) { const { $player } = art.template; events.proxy($player, "mousemove", (event) => { - art.emit("mousemove", event); + if (!isClosing(art)) + art.emit("mousemove", event); }); } +function eventSubscriptions(art) { + return (name, callback) => { + if (isClosing(art)) + return; + const listener = (...args) => { + if (!isClosing(art)) + return callback(...args); + }; + art.on(name, listener); + getScope(art).add(() => { + art.off(name, listener); + }); + }; +} function resizeInit(art, events) { const { option, constructor } = art; - art.on("resize", () => { + const on = eventSubscriptions(art); + on("resize", () => { const { aspectRatio: aspectRatio2, notice } = art; - if (art.state === "standard" && option.autoSize) { + if (art.state === "standard" && option.autoSize) art.autoSize(); - } + if (isClosing(art)) + return; art.aspectRatio = aspectRatio2; - notice.show = ""; + if (!isClosing(art)) + notice.show = ""; }); const scope = getScope(art); let cancel = () => { }; - const resizeFn = () => { + const resize = () => { + if (isClosing(art)) + return; cancel(); cancel = timeout(scope, () => art.emit("resize"), constructor.RESIZE_TIME); }; - art.on("window:orientationchange", () => resizeFn()); - art.on("window:resize", () => resizeFn()); - if (screen && screen.orientation && screen.orientation.onchange) { - events.proxy(screen.orientation, "change", () => resizeFn()); - } + on("window:orientationchange", resize); + on("window:resize", resize); + const orientation = art.template.$player.ownerDocument.defaultView?.screen?.orientation; + if (typeof orientation?.addEventListener === "function") + events.proxy(orientation, "change", resize); } function updateInit(art) { - if (art.constructor.USE_RAF) { - const scope = getScope(art); - let cancel = () => { - }; - (function update() { - if (art.playing) { - art.emit("raf"); - } - if (!art.isDestroy) { - cancel = animationFrame(scope, update); - } - })(); - art.on("destroy", () => { - cancel(); - }); - } + if (!art.constructor.USE_RAF) + return; + const scope = getScope(art); + let cancel = () => { + }; + const update = () => { + if (isClosing(art)) + return; + if (art.playing) + art.emit("raf"); + if (!isClosing(art)) + cancel = animationFrame(scope, update); + }; + update(); + eventSubscriptions(art)("destroy", () => cancel()); +} +function inViewport(element, offset) { + const rect = element.getBoundingClientRect(); + const document2 = element.ownerDocument; + const window2 = document2.defaultView; + const height = window2?.innerHeight || document2.documentElement.clientHeight; + const width = window2?.innerWidth || document2.documentElement.clientWidth; + const vertical = rect.top - offset <= height && rect.top + rect.height + offset >= 0; + const horizontal = rect.left - offset <= width + offset && rect.left + rect.width + offset >= 0; + return vertical && horizontal; } function viewInit(art) { - const { - option, - constructor, - template: { $container } - } = art; - const scrollFn = throttle(() => { - art.emit("view", isInViewport($container, constructor.SCROLL_GAP)); - }, constructor.SCROLL_TIME); - art.on("window:scroll", () => scrollFn()); - art.on("view", (state2) => { - if (option.autoMini) { - art.mini = !state2; - } + const { option, constructor, template: { $container } } = art; + const delay = constructor.SCROLL_TIME; + const scope = getScope(art); + const on = eventSubscriptions(art); + let waiting = false; + on("window:scroll", () => { + if (waiting) + return; + art.emit("view", inViewport($container, constructor.SCROLL_GAP)); + if (isClosing(art)) + return; + waiting = true; + timeout(scope, () => { + waiting = false; + }, delay); + }); + on("view", (visible) => { + if (option.autoMini) + art.mini = !visible; }); } -const scopes$2 = /* @__PURE__ */ new WeakMap(); class Events { constructor(art) { this.destroyEvents = /* @__PURE__ */ new Set(); - const scope = getScope(art); - scopes$2.set(this, scope); - scope.add(() => this.destroy()); + ownListeners(this, art); + getScope(art).add(() => { + this.destroy(); + }); this.proxy = this.proxy.bind(this); this.hover = this.hover.bind(this); clickInit(art, this); @@ -2492,116 +2758,142 @@ class Events { updateInit(art); } proxy(target, name, callback, option = {}) { - if (Array.isArray(name)) { - return name.map((item) => this.proxy(target, item, callback, option)); - } - if (scopes$2.get(this).closed) - return () => { - }; - target.addEventListener(name, callback, option); - const destroy = () => target.removeEventListener(name, callback, option); - this.destroyEvents.add(destroy); - return destroy; + return Array.isArray(name) ? proxyListener(this, target, name, callback, option) : proxyListener(this, target, name, callback, option); } hover(target, mouseenter, mouseleave) { - if (mouseenter) { + if (mouseenter) this.proxy(target, "mouseenter", mouseenter); - } - if (mouseleave) { + if (mouseleave) this.proxy(target, "mouseleave", mouseleave); - } } - remove(destroyEvent) { - if (this.destroyEvents.has(destroyEvent)) { - try { - destroyEvent(); - } catch (error2) { - console.warn("Failed to remove event listener:", error2); - } finally { - this.destroyEvents.delete(destroyEvent); - } - } + remove(dispose) { + removeListener(this, dispose); } destroy() { - for (const destroyEvent of this.destroyEvents) { - try { - destroyEvent(); - } catch (error2) { - console.warn("Failed to destroy event listener:", error2); - } - } - this.destroyEvents.clear(); + destroyListeners(this); } } +function defaultHotkeys(art) { + const { constructor } = art; + return { + Escape: () => { + if (art.fullscreenWeb) + art.fullscreenWeb = false; + }, + Space: () => { + silencePromise(art.toggle()); + }, + ArrowLeft: () => { + art.backward = constructor.SEEK_STEP; + }, + ArrowUp: () => { + art.volume += constructor.VOLUME_STEP; + }, + ArrowRight: () => { + art.forward = constructor.SEEK_STEP; + }, + ArrowDown: () => { + art.volume -= constructor.VOLUME_STEP; + } + }; +} +function asElement(target) { + if (target && target.nodeType === 1) + return target; +} +function eventDocument(event, fallback) { + const target = event.target; + return target?.nodeType === 9 ? target : target?.ownerDocument || event.view?.document || fallback; +} +function editable(target) { + const tag = target.tagName.toUpperCase(); + if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") + return true; + return target.isContentEditable; +} +function acceptsHotkey(event, fallback) { + if (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); + while (active2?.shadowRoot?.activeElement) + active2 = asElement(active2.shadowRoot.activeElement); + if (active2 && editable(active2)) + return false; + const first = asElement(event.composedPath?.()[0]) || asElement(event.target); + return !first || !editable(first); +} +const states$2 = /* @__PURE__ */ new WeakMap(); class Hotkey { constructor(art) { this.art = art; this.keys = {}; - if (!isMobile) { + states$2.set(this, { subscribed: false }); + if (!isMobile) this.init(); - } } init() { - const { constructor } = this.art; - if (this.art.option.hotkey) { - this.add("Escape", () => { - if (this.art.fullscreenWeb) { - this.art.fullscreenWeb = false; - } - }); - this.add("Space", () => { - silencePromise(this.art.toggle()); - }); - this.add("ArrowLeft", () => { - this.art.backward = constructor.SEEK_STEP; - }); - this.add("ArrowUp", () => { - this.art.volume += constructor.VOLUME_STEP; - }); - this.add("ArrowRight", () => { - this.art.forward = constructor.SEEK_STEP; - }); - this.add("ArrowDown", () => { - this.art.volume -= constructor.VOLUME_STEP; - }); + const art = this.art; + if (isClosing(art)) + return; + const state2 = states$2.get(this); + if (art.option.hotkey) { + if (!state2.defaults) { + const callbacks = defaultHotkeys(art); + state2.defaults = () => { + for (const key of Object.keys(callbacks)) + this.add(key, callbacks[key]); + }; + } + state2.defaults(); } - this.art.on("document:keydown", (event) => { - if (this.art.isFocus) { - const tag = document.activeElement.tagName.toUpperCase(); - const editable = document.activeElement.getAttribute("contenteditable"); - if (tag !== "INPUT" && tag !== "TEXTAREA" && editable !== "" && editable !== "true" && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { - const events = this.keys[event.code]; - if (events) { - event.preventDefault(); - for (let index = 0; index < events.length; index++) { - events[index].call(this.art, event); - } - this.art.emit("hotkey", event); + if (state2.subscribed) + return; + state2.subscribed = true; + const onKeydown = (event) => { + if (isClosing(art)) + return; + if (art.isFocus && acceptsHotkey(event, art.template.$player.ownerDocument)) { + const callbacks = Object.prototype.hasOwnProperty.call(this.keys, event.code) ? this.keys[event.code] : void 0; + if (callbacks) { + event.preventDefault(); + for (let index = 0; index < callbacks.length; index++) { + if (isClosing(art)) + return; + callbacks[index].call(art, event); } + if (isClosing(art)) + return; + art.emit("hotkey", event); } } - this.art.emit("keydown", event); + if (!isClosing(art)) + art.emit("keydown", event); + }; + art.on("document:keydown", onKeydown); + getScope(art).add(() => { + state2.subscribed = false; + art.off("document:keydown", onKeydown); }); } - add(key, event) { - if (this.keys[key]) { - if (!this.keys[key].includes(event)) { - this.keys[key].push(event); - } + add(key, callback) { + const existing = Object.prototype.hasOwnProperty.call(this.keys, key) ? this.keys[key] : void 0; + if (existing) { + if (!existing.includes(callback)) + existing.push(callback); } else { - this.keys[key] = [event]; + Object.defineProperty(this.keys, key, { value: [callback], enumerable: true, configurable: true, writable: true }); } return this; } - remove(key, event) { - if (this.keys[key]) { - const index = this.keys[key].indexOf(event); - if (index !== -1) { - this.keys[key].splice(index, 1); - } - if (this.keys[key].length === 0) { + remove(key, callback) { + const existing = Object.prototype.hasOwnProperty.call(this.keys, key) ? this.keys[key] : void 0; + if (existing) { + const index = existing.indexOf(callback); + if (index !== -1) + existing.splice(index, 1); + if (existing.length === 0) delete this.keys[key]; - } } return this; } @@ -3114,75 +3406,6 @@ function showMediaUI(art, changes, active2) { art[name].show = value; } } -const current = /* @__PURE__ */ new WeakMap(); -const assignments = /* @__PURE__ */ new WeakMap(); -const sources = /* @__PURE__ */ new WeakMap(); -function getSourceScope(owner) { - return sources.get(owner) || getScope(owner); -} -function captureSource(owner) { - const operation = current.get(owner); - const source = sources.get(owner); - return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed); -} -function beginSource(owner) { - const previous = sources.get(owner); - const source = getScope(owner).child(); - const scope = source.child(); - sources.set(owner, source); - source.add(() => { - if (sources.get(owner) === source) - sources.delete(owner); - }); - const operation = { - scope, - assigned: false, - acceptingEvents: false, - active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation - }; - current.set(owner, operation); - scope.add(() => { - if (current.get(owner) === operation) - current.delete(owner); - operation.onAssigned = void 0; - operation.onError = void 0; - }); - previous?.dispose(); - return operation; -} -function takeAssignment(owner) { - const operation = assignments.get(owner); - assignments.delete(owner); - return operation || beginSource(owner); -} -function finishAssignment(operation) { - operation.assigned = true; - const callback = operation.onAssigned; - operation.onAssigned = void 0; - if (operation.active()) - callback?.(); -} -function assignUrl(owner, operation, url) { - assignments.set(owner, operation); - operation.acceptingEvents = true; - try { - owner.url = url; - } finally { - if (assignments.get(owner) === operation) { - assignments.delete(owner); - finishAssignment(operation); - } - } -} -function failSource(operation, error2) { - if (!operation.active()) - return; - if (operation.onError) - operation.onError(error2); - else - console.warn("Failed to initialize ArtPlayer source:", error2); - operation.scope.dispose(); -} function installEnded(art) { const { option } = art; listenMedia(art, "video:ended", () => { diff --git a/packages/artplayer/src/control/progress/position.ts b/packages/artplayer/src/control/progress/position.ts index 38a47bad1..8bc31deca 100644 --- a/packages/artplayer/src/control/progress/position.ts +++ b/packages/artplayer/src/control/progress/position.ts @@ -1,8 +1,15 @@ -import type { ControlHost } from '../types' import { clamp, getRect, isMobile, secondToTime } from '../../utils' export type ProgressEvent = MouseEvent | TouchEvent -type ProgressPositionHost = Pick +export interface ProgressPositionHost { + template: { $progress: HTMLElement } + duration: number + isRotate: boolean + top: number + height: number + seek: number | string + emit: (name: 'setBar', kind: 'played', percentage: number, event: ProgressEvent) => unknown +} export function getPosFromEvent(art: ProgressPositionHost, event: ProgressEvent) { const { $progress } = art.template @@ -15,16 +22,18 @@ export function getPosFromEvent(art: ProgressPositionHost, event: ProgressEvent) return { second, time, width, percentage } } -export function setCurrentTime(art: ProgressPositionHost, event: ProgressEvent) { +export function setCurrentTime(art: ProgressPositionHost, event: ProgressEvent, active: () => boolean = () => true) { if (art.isRotate) { const percentage = ((event as TouchEvent).touches[0]!.clientY - art.top) / art.height const second = percentage * art.duration art.emit('setBar', 'played', percentage, event) - art.seek = second + if (active()) + art.seek = second } else { const { second, percentage } = getPosFromEvent(art, event) art.emit('setBar', 'played', percentage, event) - art.seek = second + if (active()) + art.seek = second } } diff --git a/packages/artplayer/src/events/clickInit.js b/packages/artplayer/src/events/clickInit.js deleted file mode 100644 index 3e86a09c4..000000000 --- a/packages/artplayer/src/events/clickInit.js +++ /dev/null @@ -1,65 +0,0 @@ -import { includeFromEvent, isMobile, silencePromise } from '../utils' - -export default function clickInit(art, events) { - const { - constructor, - template: { $player, $video }, - } = art - - function onDocumentClick(event) { - if (includeFromEvent(event, $player)) { - art.isInput = event.target.tagName === 'INPUT' - art.isFocus = true - art.emit('focus', event) - } - else { - art.isInput = false - art.isFocus = false - art.emit('blur', event) - } - } - - art.on('document:click', onDocumentClick) - art.on('document:contextmenu', onDocumentClick) - - let clickTimes = [] - events.proxy($video, 'click', (event) => { - const now = Date.now() - clickTimes.push(now) - const { MOBILE_CLICK_PLAY, DBCLICK_TIME, MOBILE_DBCLICK_PLAY, DBCLICK_FULLSCREEN } = constructor - - const clicks = clickTimes.filter(t => now - t <= DBCLICK_TIME) - switch (clicks.length) { - case 1: - art.emit('click', event) - - if (isMobile) { - if (!art.isLock && MOBILE_CLICK_PLAY) { - silencePromise(art.toggle()) - } - } - else { - silencePromise(art.toggle()) - } - clickTimes = clicks - break - case 2: - art.emit('dblclick', event) - - if (isMobile) { - if (!art.isLock && MOBILE_DBCLICK_PLAY) { - silencePromise(art.toggle()) - } - } - else { - if (DBCLICK_FULLSCREEN) { - art.fullscreen = !art.fullscreen - } - } - clickTimes = [] - break - default: - clickTimes = [] - } - }) -} diff --git a/packages/artplayer/src/events/clickInit.ts b/packages/artplayer/src/events/clickInit.ts new file mode 100644 index 000000000..2c3b22e8d --- /dev/null +++ b/packages/artplayer/src/events/clickInit.ts @@ -0,0 +1,45 @@ +import type { ClickHost, PointerRegistry } from '../input/pointer-types' +import { pointerFocus } from '../input/pointer-focus' +import { isClosing } from '../lifecycle/instance' +import { isMobile } from '../utils/compatibility' +import { silencePromise } from '../utils/error' + +export default function clickInit(art: ClickHost, events: Pick): void { + const { constructor, template: { $video } } = art + pointerFocus(art) + + let clickTimes: number[] = [] + events.proxy($video, 'click', (event) => { + if (isClosing(art)) + return + const now = Date.now() + clickTimes.push(now) + const { MOBILE_CLICK_PLAY, DBCLICK_TIME, MOBILE_DBCLICK_PLAY, DBCLICK_FULLSCREEN } = constructor + const clicks = clickTimes.filter(t => now - t <= DBCLICK_TIME) + switch (clicks.length) { + case 1: + art.emit('click', event) + if (isClosing(art)) + return + if (!isMobile || (!art.isLock && MOBILE_CLICK_PLAY)) + silencePromise(art.toggle()) + clickTimes = clicks + break + case 2: + art.emit('dblclick', event) + if (isClosing(art)) + return + if (isMobile) { + if (!art.isLock && MOBILE_DBCLICK_PLAY) + silencePromise(art.toggle()) + } + else if (DBCLICK_FULLSCREEN) { + art.fullscreen = !art.fullscreen + } + clickTimes = [] + break + default: + clickTimes = [] + } + }) +} diff --git a/packages/artplayer/src/events/gestureInit.js b/packages/artplayer/src/events/gestureInit.js deleted file mode 100644 index 3c699c1c5..000000000 --- a/packages/artplayer/src/events/gestureInit.js +++ /dev/null @@ -1,104 +0,0 @@ -import { setCurrentTime } from '../control/progress' -import { clamp, isMobile, secondToTime } from '../utils' - -function GetSlideAngle(dx, dy) { - return (Math.atan2(dy, dx) * 180) / Math.PI -} - -function GetSlideDirection(startX, startY, endX, endY) { - const dy = startY - endY - const dx = endX - startX - let result = 0 - - if (Math.abs(dx) < 2 && Math.abs(dy) < 2) { - return result - } - - const angle = GetSlideAngle(dx, dy) - if (angle >= -45 && angle < 45) { - result = 4 - } - else if (angle >= 45 && angle < 135) { - result = 1 - } - else if (angle >= -135 && angle < -45) { - result = 2 - } - else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) { - result = 3 - } - - return result -} - -export default function gestureInit(art, events) { - if (isMobile && !art.option.isLive) { - const { $video, $progress } = art.template - - let touchTarget = null - let isDragging = false - let startX = 0 - let startY = 0 - let startTime = 0 - - const onTouchStart = (event) => { - if (event.touches.length === 1 && !art.isLock) { - if (touchTarget === $progress) { - setCurrentTime(art, event) - } - - isDragging = true - const { pageX, pageY } = event.touches[0] - startX = pageX - startY = pageY - startTime = art.currentTime - } - } - - const onTouchMove = (event) => { - if (event.touches.length === 1 && isDragging && art.duration) { - const { pageX, pageY } = event.touches[0] - const direction = GetSlideDirection(startX, startY, pageX, pageY) - const isHorizontal = [3, 4].includes(direction) - const isVertical = [1, 2].includes(direction) - const isLegal = (isHorizontal && !art.isRotate) || (isVertical && art.isRotate) - if (isLegal) { - const ratioX = clamp((pageX - startX) / art.width, -1, 1) - const ratioY = clamp((pageY - startY) / art.height, -1, 1) - const ratio = art.isRotate ? ratioY : ratioX - const TOUCH_MOVE_RATIO = touchTarget === $video ? art.constructor.TOUCH_MOVE_RATIO : 1 - const currentTime = clamp(startTime + art.duration * ratio * TOUCH_MOVE_RATIO, 0, art.duration) - art.seek = currentTime - art.emit('setBar', 'played', clamp(currentTime / art.duration, 0, 1), event) - art.notice.show = `${secondToTime(currentTime)} / ${secondToTime(art.duration)}` - } - } - } - - const onTouchEnd = () => { - if (isDragging) { - startX = 0 - startY = 0 - startTime = 0 - isDragging = false - touchTarget = null - } - } - - if (art.option.gesture) { - events.proxy($video, 'touchstart', (event) => { - touchTarget = $video - onTouchStart(event) - }) - events.proxy($video, 'touchmove', onTouchMove) - } - - events.proxy($progress, 'touchstart', (event) => { - touchTarget = $progress - onTouchStart(event) - }) - - events.proxy($progress, 'touchmove', onTouchMove) - art.on('document:touchend', onTouchEnd) - } -} diff --git a/packages/artplayer/src/events/gestureInit.ts b/packages/artplayer/src/events/gestureInit.ts new file mode 100644 index 000000000..4beac6ec9 --- /dev/null +++ b/packages/artplayer/src/events/gestureInit.ts @@ -0,0 +1,19 @@ +import type { GestureHost } from '../input/gesture-types' +import type { PointerRegistry } from '../input/pointer-types' +import { gestureController } from '../input/gesture-controller' +import { isMobile } from '../utils/compatibility' + +export default function gestureInit(art: GestureHost, events: Pick): void { + if (!isMobile || art.option.isLive) + return + const { $video, $progress } = art.template + const gesture = gestureController(art) + const bind = (target: EventTarget) => { + events.proxy(target, 'touchstart', event => gesture.start(target, event as TouchEvent)) + events.proxy(target, 'touchmove', event => gesture.move(event as TouchEvent)) + events.proxy(target, 'touchcancel', gesture.cancel) + } + if (art.option.gesture) + bind($video) + bind($progress) +} diff --git a/packages/artplayer/src/events/global-types.ts b/packages/artplayer/src/events/global-types.ts new file mode 100644 index 000000000..de6fc73b9 --- /dev/null +++ b/packages/artplayer/src/events/global-types.ts @@ -0,0 +1,17 @@ +import type { Disposer, Listener } from './listener-registry' + +export interface GlobalEventSource { + document?: Document + window?: Window +} + +export interface GlobalEventHost { + template: { $player: HTMLElement } + emit: (name: string, event: Event) => unknown +} + +export interface GlobalEventRegistry { + proxy: (target: EventTarget, name: string, listener: Listener) => Disposer + remove: (dispose: Disposer) => void + bindGlobalEvents?: (source?: GlobalEventSource) => void +} diff --git a/packages/artplayer/src/events/globalInit.js b/packages/artplayer/src/events/globalInit.js deleted file mode 100644 index d605b704e..000000000 --- a/packages/artplayer/src/events/globalInit.js +++ /dev/null @@ -1,52 +0,0 @@ -export default function globalInit(art, events) { - const documentEvents = [ - 'click', - 'mouseup', - 'keydown', - 'touchend', - 'touchmove', - 'mousemove', - 'pointerup', - 'contextmenu', - 'pointermove', - 'visibilitychange', - 'webkitfullscreenchange', - ] - - const windowEvents = [ - 'resize', - 'scroll', - 'orientationchange', - ] - - const destroyEvents = [] - - function bindGlobalEvents(source = {}) { - for (let index = 0; index < destroyEvents.length; index++) { - events.remove(destroyEvents[index]) - } - - destroyEvents.length = 0 - - const { $player } = art.template - - documentEvents.forEach((name) => { - const doc = source.document || $player.ownerDocument || document - const destroy = events.proxy(doc, name, (event) => { - art.emit(`document:${name}`, event) - }) - destroyEvents.push(destroy) - }) - - windowEvents.forEach((name) => { - const win = source.window || $player.ownerDocument?.defaultView || window - const destroy = events.proxy(win, name, (event) => { - art.emit(`window:${name}`, event) - }) - destroyEvents.push(destroy) - }) - } - - bindGlobalEvents() - events.bindGlobalEvents = bindGlobalEvents -} diff --git a/packages/artplayer/src/events/globalInit.ts b/packages/artplayer/src/events/globalInit.ts new file mode 100644 index 000000000..856423b46 --- /dev/null +++ b/packages/artplayer/src/events/globalInit.ts @@ -0,0 +1,80 @@ +import type { GlobalEventHost, GlobalEventRegistry, GlobalEventSource } from './global-types' +import type { Disposer } from './listener-registry' +import { getScope, isClosing } from '../lifecycle/instance' + +const documentEvents = [ + 'click', + 'mouseup', + 'keydown', + 'touchend', + 'touchcancel', + 'touchmove', + 'mousemove', + 'pointerup', + 'contextmenu', + 'pointermove', + 'visibilitychange', + 'webkitfullscreenchange', +] +const windowEvents = ['resize', 'scroll', 'orientationchange'] + +interface Binding { + disposers: Disposer[] +} + +export default function globalInit(art: GlobalEventHost, events: GlobalEventRegistry): void { + let active: Binding | undefined + let generation = 0 + getScope(art).add(() => { + active = undefined + generation++ + return undefined + }) + + const release = (binding: Binding | undefined) => { + if (binding) { + for (const dispose of binding.disposers) + events.remove(dispose) + binding.disposers.length = 0 + } + } + + function bindGlobalEvents(source: GlobalEventSource = {}): void { + if (isClosing(art)) + return + const current = ++generation + const binding: Binding = { disposers: [] } + const cancelled = () => current !== generation || isClosing(art) + try { + const { $player } = art.template + const doc = source.document || $player.ownerDocument || document + const win = source.window || $player.ownerDocument?.defaultView || window + const register = (target: EventTarget, names: string[], prefix: string) => { + for (const name of names) { + if (cancelled()) + return + binding.disposers.push(events.proxy(target, name, (event) => { + if (active === binding && !isClosing(art)) + art.emit(`${prefix}:${name}`, event) + })) + } + } + register(doc, documentEvents, 'document') + register(win, windowEvents, 'window') + } + catch (error) { + release(binding) + throw error + } + if (cancelled()) { + release(binding) + return + } + const previous = active + active = binding + release(previous) + } + + bindGlobalEvents() + events.bindGlobalEvents = bindGlobalEvents +} diff --git a/packages/artplayer/src/events/hoverInit.js b/packages/artplayer/src/events/hoverInit.js deleted file mode 100644 index f310dcaf7..000000000 --- a/packages/artplayer/src/events/hoverInit.js +++ /dev/null @@ -1,17 +0,0 @@ -import { addClass, removeClass } from '../utils' - -export default function hoverInit(art, events) { - const { $player } = art.template - - events.hover( - $player, - (event) => { - addClass($player, 'art-hover') - art.emit('hover', true, event) - }, - (event) => { - removeClass($player, 'art-hover') - art.emit('hover', false, event) - }, - ) -} diff --git a/packages/artplayer/src/events/hoverInit.ts b/packages/artplayer/src/events/hoverInit.ts new file mode 100644 index 000000000..9ed97d673 --- /dev/null +++ b/packages/artplayer/src/events/hoverInit.ts @@ -0,0 +1,22 @@ +import type { HoverHost, PointerRegistry } from '../input/pointer-types' +import { isClosing } from '../lifecycle/instance' +import { addClass, removeClass } from '../utils/dom' + +export default function hoverInit(art: HoverHost, events: Pick): void { + const { $player } = art.template + events.hover( + $player, + (event) => { + if (isClosing(art)) + return + addClass($player, 'art-hover') + art.emit('hover', true, event) + }, + (event) => { + if (isClosing(art)) + return + removeClass($player, 'art-hover') + art.emit('hover', false, event) + }, + ) +} diff --git a/packages/artplayer/src/events/index.js b/packages/artplayer/src/events/index.js deleted file mode 100644 index 215117668..000000000 --- a/packages/artplayer/src/events/index.js +++ /dev/null @@ -1,80 +0,0 @@ -import { getScope } from '../lifecycle/instance' -import clickInit from './clickInit' -import gestureInit from './gestureInit' -import globalInit from './globalInit' -import hoverInit from './hoverInit' -import moveInit from './moveInit' -import resizeInit from './resizeInit' -import updateInit from './updateInit' -import viewInit from './viewInit' - -const scopes = new WeakMap() - -export default class Events { - constructor(art) { - this.destroyEvents = new Set() - const scope = getScope(art) - scopes.set(this, scope) - scope.add(() => this.destroy()) - this.proxy = this.proxy.bind(this) - this.hover = this.hover.bind(this) - - clickInit(art, this) - hoverInit(art, this) - moveInit(art, this) - resizeInit(art, this) - gestureInit(art, this) - viewInit(art, this) - globalInit(art, this) - updateInit(art, this) - } - - proxy(target, name, callback, option = {}) { - if (Array.isArray(name)) { - return name.map(item => this.proxy(target, item, callback, option)) - } - - if (scopes.get(this).closed) - return () => {} - - target.addEventListener(name, callback, option) - const destroy = () => target.removeEventListener(name, callback, option) - this.destroyEvents.add(destroy) - return destroy - } - - hover(target, mouseenter, mouseleave) { - if (mouseenter) { - this.proxy(target, 'mouseenter', mouseenter) - } - if (mouseleave) { - this.proxy(target, 'mouseleave', mouseleave) - } - } - - remove(destroyEvent) { - if (this.destroyEvents.has(destroyEvent)) { - try { - destroyEvent() - } - catch (error) { - console.warn('Failed to remove event listener:', error) - } - finally { - this.destroyEvents.delete(destroyEvent) - } - } - } - - destroy() { - for (const destroyEvent of this.destroyEvents) { - try { - destroyEvent() - } - catch (error) { - console.warn('Failed to destroy event listener:', error) - } - } - this.destroyEvents.clear() - } -} diff --git a/packages/artplayer/src/events/index.ts b/packages/artplayer/src/events/index.ts new file mode 100644 index 000000000..2c47def88 --- /dev/null +++ b/packages/artplayer/src/events/index.ts @@ -0,0 +1,59 @@ +import type { GlobalEventSource } from './global-types' +import type { Disposer, Listener } from './listener-registry' +import type { EventsHost } from './types' +import { getScope } from '../lifecycle/instance' +import clickInit from './clickInit' +import gestureInit from './gestureInit' +import globalInit from './globalInit' +import hoverInit from './hoverInit' +import { destroyListeners, ownListeners, proxyListener, removeListener } from './listener-registry' +import moveInit from './moveInit' +import resizeInit from './resizeInit' +import updateInit from './updateInit' +import viewInit from './viewInit' + +export default class Events { + declare destroyEvents: Set + declare bindGlobalEvents: (source?: GlobalEventSource) => void + + constructor(art: EventsHost) { + this.destroyEvents = new Set() + ownListeners(this, art) + getScope(art).add(() => { + this.destroy() + }) + this.proxy = this.proxy.bind(this) + this.hover = this.hover.bind(this) + + clickInit(art, this) + hoverInit(art, this) + moveInit(art, this) + resizeInit(art, this) + gestureInit(art, this) + viewInit(art) + globalInit(art, this) + updateInit(art) + } + + proxy(target: EventTarget, name: string, callback: Listener, option?: boolean | AddEventListenerOptions | null): Disposer + proxy(target: EventTarget, name: string[], callback: Listener, option?: boolean | AddEventListenerOptions | null): Disposer[] + proxy(target: EventTarget, name: string | string[], callback: Listener, option?: boolean | AddEventListenerOptions | null): Disposer | Disposer[] + proxy(target: EventTarget, name: string | string[], callback: Listener, option: boolean | AddEventListenerOptions | null = {}): Disposer | Disposer[] { + return Array.isArray(name) ? proxyListener(this, target, name, callback, option) : proxyListener(this, target, name, callback, option) + } + + hover(target: EventTarget, mouseenter?: (event: Event) => unknown, mouseleave?: (event: Event) => unknown): void { + if (mouseenter) + this.proxy(target, 'mouseenter', mouseenter) + if (mouseleave) + this.proxy(target, 'mouseleave', mouseleave) + } + + remove(dispose: Disposer): void { + removeListener(this, dispose) + } + + destroy(): void { + destroyListeners(this) + } +} diff --git a/packages/artplayer/src/events/listener-registry.ts b/packages/artplayer/src/events/listener-registry.ts new file mode 100644 index 000000000..b4a821360 --- /dev/null +++ b/packages/artplayer/src/events/listener-registry.ts @@ -0,0 +1,135 @@ +import type ResourceScope from '../lifecycle/scope' +import { getScope } from '../lifecycle/instance' + +export type Disposer = () => void +export type Listener = EventListenerOrEventListenerObject | null +export interface ListenerRegistry { + destroyEvents: Set +} + +interface State { + scope: ResourceScope + cleaning: boolean +} +const states = new WeakMap() + +export function ownListeners(registry: ListenerRegistry, art: object): void { + states.set(registry, { scope: getScope(art), cleaning: false }) +} + +function stateOf(registry: ListenerRegistry): State { + const state = states.get(registry) + if (!state) + throw new Error('ArtPlayer event registry has not been initialized') + return state +} + +export function proxyListener(registry: ListenerRegistry, target: EventTarget, names: string[], callback: Listener, option?: boolean | AddEventListenerOptions | null): Disposer[] +export function proxyListener(registry: ListenerRegistry, target: EventTarget, names: string, callback: Listener, option?: boolean | AddEventListenerOptions | null): Disposer +export function proxyListener(registry: ListenerRegistry, target: EventTarget, names: string | string[], callback: Listener, option: boolean | AddEventListenerOptions | null = {}): Disposer | Disposer[] { + if (Array.isArray(names)) { + const created: Disposer[] = [] + try { + return names.map((name) => { + const dispose = proxyListener(registry, target, name, callback, option) + created.push(dispose) + return dispose + }) + } + catch (error) { + for (const dispose of created.reverse()) { + try { + dispose() + } + catch (cleanupError) { + console.warn('Failed to roll back event listener:', cleanupError) + } + } + throw error + } + } + const name = names + const state = stateOf(registry) + if (state.scope.closed || state.cleaning) + return () => {} + // Snapshot native dictionary values, especially capture, without wrapping the callback. + const options = typeof option === 'boolean' + ? option + : { + capture: Boolean(option?.capture), + once: Boolean(option?.once), + passive: option?.passive, + signal: option?.signal, + } + const capture = typeof options === 'boolean' ? options : options.capture + const signal = typeof options === 'boolean' ? undefined : options.signal + if (state.scope.closed || state.cleaning || signal?.aborted) + return () => {} + let active = true + function clean(force = false): void { + if (!active && !force) + return + target.removeEventListener(name, callback, capture) + signal?.removeEventListener('abort', dispose) + active = false + registry.destroyEvents.delete(dispose) + } + function dispose(): void { + clean() + } + registry.destroyEvents.add(dispose) + try { + target.addEventListener(name, callback, options) + // A custom target may synchronously destroy the player before adding the listener. + if (!active || state.scope.closed || state.cleaning) + clean(true) + else if (signal?.aborted) + dispose() + else + signal?.addEventListener('abort', dispose, { once: true }) + } + catch (error) { + try { + clean(true) + } + catch (cleanupError) { + console.warn('Failed to roll back event listener:', cleanupError) + } + throw error + } + return dispose +} + +export function removeListener(registry: ListenerRegistry, dispose: Disposer): void { + if (!registry.destroyEvents.has(dispose)) + return + try { + dispose() + registry.destroyEvents.delete(dispose) + } + catch (error) { + // Retain a failed removal so a later remove/destroy can retry it. + console.warn('Failed to remove event listener:', error) + } +} + +export function destroyListeners(registry: ListenerRegistry): void { + const state = stateOf(registry) + if (state.cleaning) + return + state.cleaning = true + try { + for (const dispose of registry.destroyEvents) { + try { + dispose() + registry.destroyEvents.delete(dispose) + } + catch (error) { + console.warn('Failed to destroy event listener:', error) + } + } + } + finally { + state.cleaning = false + } +} diff --git a/packages/artplayer/src/events/moveInit.js b/packages/artplayer/src/events/moveInit.js deleted file mode 100644 index d618d93e0..000000000 --- a/packages/artplayer/src/events/moveInit.js +++ /dev/null @@ -1,7 +0,0 @@ -export default function moveInit(art, events) { - const { $player } = art.template - - events.proxy($player, 'mousemove', (event) => { - art.emit('mousemove', event) - }) -} diff --git a/packages/artplayer/src/events/moveInit.ts b/packages/artplayer/src/events/moveInit.ts new file mode 100644 index 000000000..debe39aef --- /dev/null +++ b/packages/artplayer/src/events/moveInit.ts @@ -0,0 +1,10 @@ +import type { MoveHost, PointerRegistry } from '../input/pointer-types' +import { isClosing } from '../lifecycle/instance' + +export default function moveInit(art: MoveHost, events: Pick): void { + const { $player } = art.template + events.proxy($player, 'mousemove', (event) => { + if (!isClosing(art)) + art.emit('mousemove', event) + }) +} diff --git a/packages/artplayer/src/events/resizeInit.js b/packages/artplayer/src/events/resizeInit.js deleted file mode 100644 index b5aae3505..000000000 --- a/packages/artplayer/src/events/resizeInit.js +++ /dev/null @@ -1,29 +0,0 @@ -import { getScope } from '../lifecycle/instance' -import { timeout } from '../lifecycle/resources' - -export default function resizeInit(art, events) { - const { option, constructor } = art - - art.on('resize', () => { - const { aspectRatio, notice } = art - if (art.state === 'standard' && option.autoSize) { - art.autoSize() - } - art.aspectRatio = aspectRatio - notice.show = '' - }) - - const scope = getScope(art) - let cancel = () => {} - const resizeFn = () => { - cancel() - cancel = timeout(scope, () => art.emit('resize'), constructor.RESIZE_TIME) - } - - art.on('window:orientationchange', () => resizeFn()) - art.on('window:resize', () => resizeFn()) - - if (screen && screen.orientation && screen.orientation.onchange) { - events.proxy(screen.orientation, 'change', () => resizeFn()) - } -} diff --git a/packages/artplayer/src/events/resizeInit.ts b/packages/artplayer/src/events/resizeInit.ts new file mode 100644 index 000000000..ffb88bf55 --- /dev/null +++ b/packages/artplayer/src/events/resizeInit.ts @@ -0,0 +1,35 @@ +import type { PointerRegistry } from '../input/pointer-types' +import type { ResizeEvents, ResizeHost } from './scheduling-types' +import { getScope, isClosing } from '../lifecycle/instance' +import { timeout } from '../lifecycle/resources' +import { eventSubscriptions } from './subscriptions' + +export default function resizeInit(art: ResizeHost, events: Pick): void { + const { option, constructor } = art + const on = eventSubscriptions(art) + on('resize', () => { + const { aspectRatio, notice } = art + if (art.state === 'standard' && option.autoSize) + art.autoSize() + if (isClosing(art)) + return + art.aspectRatio = aspectRatio + if (!isClosing(art)) + notice.show = '' + }) + + const scope = getScope(art) + let cancel = () => {} + const resize = () => { + if (isClosing(art)) + return + cancel() + cancel = timeout(scope, () => art.emit('resize'), constructor.RESIZE_TIME) + } + on('window:orientationchange', resize) + on('window:resize', resize) + + const orientation = art.template.$player.ownerDocument.defaultView?.screen?.orientation + if (typeof orientation?.addEventListener === 'function') + events.proxy(orientation, 'change', resize) +} diff --git a/packages/artplayer/src/events/scheduling-types.ts b/packages/artplayer/src/events/scheduling-types.ts new file mode 100644 index 000000000..69b9f2cb5 --- /dev/null +++ b/packages/artplayer/src/events/scheduling-types.ts @@ -0,0 +1,34 @@ +import type { SubscriptionHost } from '../component/resources' + +export interface ResizeEvents { + 'resize': [] + 'window:resize': [Event] + 'window:orientationchange': [Event] +} + +export interface ResizeHost extends SubscriptionHost { + template: { $player: HTMLElement } + option: { autoSize: boolean } + constructor: { RESIZE_TIME: number } + aspectRatio: string + state: string + autoSize: () => unknown + notice: { show: string } + emit: (name: 'resize') => unknown +} + +export interface ViewEvents { 'window:scroll': [Event], 'view': [boolean] } +export interface ViewHost extends SubscriptionHost { + template: { $container: HTMLElement } + option: { autoMini: boolean } + constructor: { SCROLL_GAP: number, SCROLL_TIME: number } + mini: boolean + emit: (name: 'view', visible: boolean) => unknown +} + +export interface RafEvents { destroy: [] } +export interface RafHost extends SubscriptionHost { + constructor: { USE_RAF: boolean } + playing: boolean + emit: (name: 'raf') => unknown +} diff --git a/packages/artplayer/src/events/subscriptions.ts b/packages/artplayer/src/events/subscriptions.ts new file mode 100644 index 000000000..3c554d9d3 --- /dev/null +++ b/packages/artplayer/src/events/subscriptions.ts @@ -0,0 +1,17 @@ +import type { SubscriptionHost } from '../component/resources' +import { getScope, isClosing } from '../lifecycle/instance' + +export function eventSubscriptions(art: SubscriptionHost) { + return (name: Name, callback: (...args: [...Events[Name]]) => unknown): void => { + if (isClosing(art)) + return + const listener = (...args: [...Events[Name]]) => { + if (!isClosing(art)) + return callback(...args) + } + art.on(name, listener) + getScope(art).add(() => { + art.off(name, listener) + }) + } +} diff --git a/packages/artplayer/src/events/types.ts b/packages/artplayer/src/events/types.ts new file mode 100644 index 000000000..d6d49038a --- /dev/null +++ b/packages/artplayer/src/events/types.ts @@ -0,0 +1,6 @@ +import type { GestureHost } from '../input/gesture-types' +import type { ClickHost, HoverHost, MoveHost } from '../input/pointer-types' +import type { GlobalEventHost } from './global-types' +import type { RafHost, ResizeHost, ViewHost } from './scheduling-types' + +export type EventsHost = ClickHost & HoverHost & MoveHost & GestureHost & GlobalEventHost & RafHost & ResizeHost & ViewHost diff --git a/packages/artplayer/src/events/updateInit.js b/packages/artplayer/src/events/updateInit.js deleted file mode 100644 index e70b6e0f3..000000000 --- a/packages/artplayer/src/events/updateInit.js +++ /dev/null @@ -1,23 +0,0 @@ -import { getScope } from '../lifecycle/instance' -import { animationFrame } from '../lifecycle/resources' - -export default function updateInit(art) { - if (art.constructor.USE_RAF) { - const scope = getScope(art) - let cancel = () => {}; - - (function update() { - if (art.playing) { - art.emit('raf') - } - - if (!art.isDestroy) { - cancel = animationFrame(scope, update) - } - })() - - art.on('destroy', () => { - cancel() - }) - } -} diff --git a/packages/artplayer/src/events/updateInit.ts b/packages/artplayer/src/events/updateInit.ts new file mode 100644 index 000000000..e411f09ec --- /dev/null +++ b/packages/artplayer/src/events/updateInit.ts @@ -0,0 +1,21 @@ +import type { RafEvents, RafHost } from './scheduling-types' +import { getScope, isClosing } from '../lifecycle/instance' +import { animationFrame } from '../lifecycle/resources' +import { eventSubscriptions } from './subscriptions' + +export default function updateInit(art: RafHost): void { + if (!art.constructor.USE_RAF) + return + const scope = getScope(art) + let cancel = () => {} + const update = () => { + if (isClosing(art)) + return + if (art.playing) + art.emit('raf') + if (!isClosing(art)) + cancel = animationFrame(scope, update) + } + update() + eventSubscriptions(art)('destroy', () => cancel()) +} diff --git a/packages/artplayer/src/events/viewInit.js b/packages/artplayer/src/events/viewInit.js deleted file mode 100644 index 9c0535fdd..000000000 --- a/packages/artplayer/src/events/viewInit.js +++ /dev/null @@ -1,21 +0,0 @@ -import { isInViewport, throttle } from '../utils' - -export default function viewInit(art) { - const { - option, - constructor, - template: { $container }, - } = art - - const scrollFn = throttle(() => { - art.emit('view', isInViewport($container, constructor.SCROLL_GAP)) - }, constructor.SCROLL_TIME) - - art.on('window:scroll', () => scrollFn()) - - art.on('view', (state) => { - if (option.autoMini) { - art.mini = !state - } - }) -} diff --git a/packages/artplayer/src/events/viewInit.ts b/packages/artplayer/src/events/viewInit.ts new file mode 100644 index 000000000..70cb9247c --- /dev/null +++ b/packages/artplayer/src/events/viewInit.ts @@ -0,0 +1,29 @@ +import type { ViewEvents, ViewHost } from './scheduling-types' +import { getScope, isClosing } from '../lifecycle/instance' +import { timeout } from '../lifecycle/resources' +import { eventSubscriptions } from './subscriptions' +import { inViewport } from './viewport' + +export default function viewInit(art: ViewHost): void { + const { option, constructor, template: { $container } } = art + const delay = constructor.SCROLL_TIME + const scope = getScope(art) + const on = eventSubscriptions(art) + let waiting = false + on('window:scroll', () => { + if (waiting) + return + art.emit('view', inViewport($container, constructor.SCROLL_GAP)) + if (isClosing(art)) + return + // Keep the leading-only throttle and its historical synchronous reentry timing. + waiting = true + timeout(scope, () => { + waiting = false + }, delay) + }) + on('view', (visible) => { + if (option.autoMini) + art.mini = !visible + }) +} diff --git a/packages/artplayer/src/events/viewport.ts b/packages/artplayer/src/events/viewport.ts new file mode 100644 index 000000000..20f10c92d --- /dev/null +++ b/packages/artplayer/src/events/viewport.ts @@ -0,0 +1,11 @@ +export function inViewport(element: HTMLElement, offset: number): boolean { + const rect = element.getBoundingClientRect() + const document = element.ownerDocument + const window = document.defaultView + const height = window?.innerHeight || document.documentElement.clientHeight + const width = window?.innerWidth || document.documentElement.clientWidth + // Retain the historical edge/gap calculations while using the actual owner viewport. + const vertical = rect.top - offset <= height && rect.top + rect.height + offset >= 0 + const horizontal = rect.left - offset <= width + offset && rect.left + rect.width + offset >= 0 + return vertical && horizontal +} diff --git a/packages/artplayer/src/hotkey.js b/packages/artplayer/src/hotkey.js deleted file mode 100644 index 2a5cd6367..000000000 --- a/packages/artplayer/src/hotkey.js +++ /dev/null @@ -1,96 +0,0 @@ -import { isMobile, silencePromise } from './utils' - -export default class Hotkey { - constructor(art) { - this.art = art - this.keys = {} - - if (!isMobile) { - this.init() - } - } - - init() { - const { constructor } = this.art - - if (this.art.option.hotkey) { - this.add('Escape', () => { - if (this.art.fullscreenWeb) { - this.art.fullscreenWeb = false - } - }) - - this.add('Space', () => { - silencePromise(this.art.toggle()) - }) - - this.add('ArrowLeft', () => { - this.art.backward = constructor.SEEK_STEP - }) - - this.add('ArrowUp', () => { - this.art.volume += constructor.VOLUME_STEP - }) - - this.add('ArrowRight', () => { - this.art.forward = constructor.SEEK_STEP - }) - - this.add('ArrowDown', () => { - this.art.volume -= constructor.VOLUME_STEP - }) - } - - this.art.on('document:keydown', (event) => { - if (this.art.isFocus) { - const tag = document.activeElement.tagName.toUpperCase() - const editable = document.activeElement.getAttribute('contenteditable') - if ( - tag !== 'INPUT' - && tag !== 'TEXTAREA' - && editable !== '' - && editable !== 'true' - && !event.altKey - && !event.ctrlKey - && !event.metaKey - && !event.shiftKey - ) { - const events = this.keys[event.code] - if (events) { - event.preventDefault() - for (let index = 0; index < events.length; index++) { - events[index].call(this.art, event) - } - this.art.emit('hotkey', event) - } - } - } - this.art.emit('keydown', event) - }) - } - - add(key, event) { - if (this.keys[key]) { - if (!this.keys[key].includes(event)) { - this.keys[key].push(event) - } - } - else { - this.keys[key] = [event] - } - return this - } - - remove(key, event) { - if (this.keys[key]) { - const index = this.keys[key].indexOf(event) - if (index !== -1) { - this.keys[key].splice(index, 1) - } - if (this.keys[key].length === 0) { - delete this.keys[key] - } - } - return this - } -} diff --git a/packages/artplayer/src/hotkey.ts b/packages/artplayer/src/hotkey.ts new file mode 100644 index 000000000..f5d818ed7 --- /dev/null +++ b/packages/artplayer/src/hotkey.ts @@ -0,0 +1,94 @@ +import type { HotkeyCallback, HotkeyHost } from './input/hotkey-types' +import { defaultHotkeys } from './input/hotkey-defaults' +import { acceptsHotkey } from './input/keyboard-focus' +import { getScope, isClosing } from './lifecycle/instance' +import { isMobile } from './utils/compatibility' + +interface State { + defaults?: () => void + subscribed: boolean +} +const states = new WeakMap() + +export default class Hotkey { + declare art: Host + declare keys: Record[]> + + constructor(art: Host) { + this.art = art + this.keys = {} + states.set(this, { subscribed: false }) + if (!isMobile) + this.init() + } + + init(): void { + const art = this.art + if (isClosing(art)) + return + const state = states.get(this)! + if (art.option.hotkey) { + if (!state.defaults) { + const callbacks = defaultHotkeys(art) + state.defaults = () => { + for (const key of Object.keys(callbacks)) + this.add(key, callbacks[key]!) + } + } + state.defaults() + } + if (state.subscribed) + return + state.subscribed = true + const onKeydown = (event: KeyboardEvent) => { + if (isClosing(art)) + return + if (art.isFocus && acceptsHotkey(event, art.template.$player.ownerDocument)) { + const callbacks = Object.prototype.hasOwnProperty.call(this.keys, event.code) ? this.keys[event.code] : undefined + if (callbacks) { + event.preventDefault() + // Keep the historical live-array mutation and callback receiver contracts. + for (let index = 0; index < callbacks.length; index++) { + if (isClosing(art)) + return + callbacks[index]!.call(art, event) + } + if (isClosing(art)) + return + art.emit('hotkey', event) + } + } + if (!isClosing(art)) + art.emit('keydown', event) + } + art.on('document:keydown', onKeydown) + getScope(art).add(() => { + state.subscribed = false + art.off('document:keydown', onKeydown) + }) + } + + add(key: string, callback: HotkeyCallback): this { + const existing = Object.prototype.hasOwnProperty.call(this.keys, key) ? this.keys[key] : undefined + if (existing) { + if (!existing.includes(callback)) + existing.push(callback) + } + else { + Object.defineProperty(this.keys, key, { value: [callback], enumerable: true, configurable: true, writable: true }) + } + return this + } + + remove(key: string, callback: HotkeyCallback): this { + const existing = Object.prototype.hasOwnProperty.call(this.keys, key) ? this.keys[key] : undefined + if (existing) { + const index = existing.indexOf(callback) + if (index !== -1) + existing.splice(index, 1) + if (existing.length === 0) + delete this.keys[key] + } + return this + } +} diff --git a/packages/artplayer/src/input/gesture-controller.ts b/packages/artplayer/src/input/gesture-controller.ts new file mode 100644 index 000000000..3f874b3b0 --- /dev/null +++ b/packages/artplayer/src/input/gesture-controller.ts @@ -0,0 +1,94 @@ +import type { Drag, GestureHost } from './gesture-types' +import { setCurrentTime } from '../control/progress/position' +import { getScope, isClosing } from '../lifecycle/instance' +import { captureSource } from '../source/operation' +import { clamp, secondToTime } from '../utils' +import { slideDirection } from './gesture-direction' + +export function gestureController(art: GestureHost) { + let drag: Drag | undefined + const cancel = () => { + drag = undefined + } + const active = (current: Drag) => drag === current && !isClosing(art) && !art.isLock + && !art.option.isLive && art.isRotate === current.rotated && current.sourceActive() + const onLock = (locked: boolean) => { + if (locked) + cancel() + } + art.on('document:touchend', cancel) + art.on('document:touchcancel', cancel) + art.on('lock', onLock) + getScope(art).add(() => { + cancel() + art.off('document:touchend', cancel) + art.off('document:touchcancel', cancel) + art.off('lock', onLock) + }) + + const start = (target: EventTarget, event: TouchEvent) => { + cancel() + const touch = event.touches[0] + if (isClosing(art) || art.isLock || art.option.isLive || event.touches.length !== 1 || !touch) + return + if (![touch.pageX, touch.pageY, touch.clientX, touch.clientY, art.currentTime].every(Number.isFinite)) + return + const current: Drag = { + target, + identifier: touch.identifier, + x: touch.pageX, + y: touch.pageY, + time: art.currentTime, + rotated: art.isRotate, + sourceActive: captureSource(art), + } + drag = current + if (target === art.template.$progress) { + const size = art.isRotate ? art.height : art.template.$progress.clientWidth + if (!Number.isFinite(size) || size <= 0 || !Number.isFinite(art.duration) || art.duration <= 0) { + cancel() + return + } + try { + setCurrentTime(art, event, () => active(current)) + } + catch (error) { + if (drag === current) + cancel() + throw error + } + if (active(current)) + current.time = art.currentTime + } + } + + const move = (event: TouchEvent) => { + const current = drag + const touch = event.touches[0] + if (!current) + return + if (!active(current) || event.touches.length !== 1 || !touch || touch.identifier !== current.identifier) { + cancel() + return + } + const size = current.rotated ? art.height : art.width + const multiplier = current.target === art.template.$video ? art.constructor.TOUCH_MOVE_RATIO : 1 + if (![touch.pageX, touch.pageY, size, art.duration, multiplier].every(Number.isFinite) || size <= 0 || art.duration <= 0) { + cancel() + return + } + const direction = slideDirection(current.x, current.y, touch.pageX, touch.pageY) + if (!(current.rotated ? direction === 1 || direction === 2 : direction === 3 || direction === 4)) + return + const distance = current.rotated ? touch.pageY - current.y : touch.pageX - current.x + const ratio = clamp(distance / size, -1, 1) + const time = clamp(current.time + art.duration * ratio * multiplier, 0, art.duration) + art.seek = time + if (!active(current)) + return + art.emit('setBar', 'played', clamp(time / art.duration, 0, 1), event) + if (active(current)) + art.notice.show = `${secondToTime(time)} / ${secondToTime(art.duration)}` + } + return { start, move, cancel } +} diff --git a/packages/artplayer/src/input/gesture-direction.ts b/packages/artplayer/src/input/gesture-direction.ts new file mode 100644 index 000000000..a7fc0eb4f --- /dev/null +++ b/packages/artplayer/src/input/gesture-direction.ts @@ -0,0 +1,16 @@ +export function slideDirection(startX: number, startY: number, endX: number, endY: number): 0 | 1 | 2 | 3 | 4 { + const dy = startY - endY + const dx = endX - startX + if (Math.abs(dx) < 2 && Math.abs(dy) < 2) + return 0 + const angle = Math.atan2(dy, dx) * 180 / Math.PI + if (angle >= -45 && angle < 45) + return 4 + if (angle >= 45 && angle < 135) + return 1 + if (angle >= -135 && angle < -45) + return 2 + if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) + return 3 + return 0 +} diff --git a/packages/artplayer/src/input/gesture-types.ts b/packages/artplayer/src/input/gesture-types.ts new file mode 100644 index 000000000..4d3ae79ae --- /dev/null +++ b/packages/artplayer/src/input/gesture-types.ts @@ -0,0 +1,26 @@ +import type { SubscriptionHost } from '../component/resources' +import type { ProgressPositionHost } from '../control/progress/position' + +export interface GestureHost extends ProgressPositionHost, SubscriptionHost<{ + 'document:touchend': [Event] + 'document:touchcancel': [Event] + 'lock': [boolean] +}> { + template: { $video: EventTarget, $progress: HTMLElement } + option: { isLive: boolean, gesture: boolean } + constructor: { TOUCH_MOVE_RATIO: number } + isLock: boolean + width: number + currentTime: number + notice: { show: string } +} + +export interface Drag { + target: EventTarget + identifier: number + x: number + y: number + time: number + rotated: boolean + sourceActive: () => boolean +} diff --git a/packages/artplayer/src/input/hotkey-defaults.ts b/packages/artplayer/src/input/hotkey-defaults.ts new file mode 100644 index 000000000..8d8cdd555 --- /dev/null +++ b/packages/artplayer/src/input/hotkey-defaults.ts @@ -0,0 +1,27 @@ +import type { HotkeyCallback, HotkeyHost } from './hotkey-types' +import { silencePromise } from '../utils/error' + +export function defaultHotkeys(art: Host): Record> { + const { constructor } = art + return { + Escape: () => { + if (art.fullscreenWeb) + art.fullscreenWeb = false + }, + Space: () => { + silencePromise(art.toggle()) + }, + ArrowLeft: () => { + art.backward = constructor.SEEK_STEP + }, + ArrowUp: () => { + art.volume += constructor.VOLUME_STEP + }, + ArrowRight: () => { + art.forward = constructor.SEEK_STEP + }, + ArrowDown: () => { + art.volume -= constructor.VOLUME_STEP + }, + } +} diff --git a/packages/artplayer/src/input/hotkey-types.ts b/packages/artplayer/src/input/hotkey-types.ts new file mode 100644 index 000000000..50deb8968 --- /dev/null +++ b/packages/artplayer/src/input/hotkey-types.ts @@ -0,0 +1,16 @@ +import type { SubscriptionHost } from '../component/resources' + +export interface HotkeyHost extends SubscriptionHost<{ 'document:keydown': [KeyboardEvent] }> { + constructor: { SEEK_STEP: number, VOLUME_STEP: number } + option: { hotkey?: boolean } + template: { $player: HTMLElement } + isFocus: boolean + fullscreenWeb: boolean + backward: number + forward: number + volume: number + toggle: () => unknown + emit: (name: 'hotkey' | 'keydown', event: KeyboardEvent) => unknown +} + +export type HotkeyCallback = (this: Host, event: KeyboardEvent) => unknown diff --git a/packages/artplayer/src/input/keyboard-focus.ts b/packages/artplayer/src/input/keyboard-focus.ts new file mode 100644 index 000000000..91cf6b675 --- /dev/null +++ b/packages/artplayer/src/input/keyboard-focus.ts @@ -0,0 +1,30 @@ +function asElement(target: EventTarget | null | undefined): HTMLElement | undefined { + if (target && (target as Node).nodeType === 1) + return target as HTMLElement +} + +function eventDocument(event: KeyboardEvent, fallback: Document): Document { + const target = event.target as Node | null + return target?.nodeType === 9 ? target as Document : target?.ownerDocument || event.view?.document || fallback +} + +function editable(target: HTMLElement): boolean { + const tag = target.tagName.toUpperCase() + if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') + return true + return target.isContentEditable +} + +export function acceptsHotkey(event: KeyboardEvent, fallback: Document): boolean { + if (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) + while (active?.shadowRoot?.activeElement) + active = asElement(active.shadowRoot.activeElement) + if (active && editable(active)) + return false + // The composed path exposes an editable descendant behind a retargeted shadow host. + const first = asElement(event.composedPath?.()[0]) || asElement(event.target) + return !first || !editable(first) +} diff --git a/packages/artplayer/src/input/pointer-focus.ts b/packages/artplayer/src/input/pointer-focus.ts new file mode 100644 index 000000000..3d809f86e --- /dev/null +++ b/packages/artplayer/src/input/pointer-focus.ts @@ -0,0 +1,21 @@ +import type { FocusHost } from './pointer-types' +import { getScope, isClosing } from '../lifecycle/instance' +import { includeFromEvent } from '../utils/dom' + +export function pointerFocus(art: FocusHost): void { + const { $player } = art.template + const onDocumentClick = (event: Event) => { + if (isClosing(art)) + return + const inside = includeFromEvent(event, $player) + art.isInput = inside && (event.target as Element | null)?.tagName === 'INPUT' + art.isFocus = inside + art.emit(inside ? 'focus' : 'blur', event) + } + art.on('document:click', onDocumentClick) + art.on('document:contextmenu', onDocumentClick) + getScope(art).add(() => { + art.off('document:click', onDocumentClick) + art.off('document:contextmenu', onDocumentClick) + }) +} diff --git a/packages/artplayer/src/input/pointer-types.ts b/packages/artplayer/src/input/pointer-types.ts new file mode 100644 index 000000000..e33009efb --- /dev/null +++ b/packages/artplayer/src/input/pointer-types.ts @@ -0,0 +1,39 @@ +import type { SubscriptionHost } from '../component/resources' +import type { Disposer, Listener } from '../events/listener-registry' + +export interface PointerRegistry { + proxy: (target: EventTarget, name: string, callback: Listener) => Disposer + hover: (target: EventTarget, enter?: (event: Event) => unknown, leave?: (event: Event) => unknown) => void +} + +export interface FocusHost extends SubscriptionHost<{ 'document:click': [Event], 'document:contextmenu': [Event] }> { + template: { $player: HTMLElement } + isInput: boolean + isFocus: boolean + emit: (name: 'focus' | 'blur', event: Event) => unknown +} + +export interface ClickHost extends FocusHost { + constructor: { + MOBILE_CLICK_PLAY: boolean + MOBILE_DBCLICK_PLAY: boolean + DBCLICK_TIME: number + DBCLICK_FULLSCREEN: boolean + } + + template: { $player: HTMLElement, $video: EventTarget } + isLock: boolean + fullscreen: boolean + toggle: () => unknown + emit: (name: 'focus' | 'blur' | 'click' | 'dblclick', event: Event) => unknown +} + +export interface HoverHost { + template: { $player: HTMLElement } + emit: (name: 'hover', state: boolean, event: Event) => unknown +} + +export interface MoveHost { + template: { $player: HTMLElement } + emit: (name: 'mousemove', event: Event) => unknown +} diff --git a/packages/artplayer/types/events.d.ts b/packages/artplayer/types/events.d.ts index 226ad4063..624bbd55a 100644 --- a/packages/artplayer/types/events.d.ts +++ b/packages/artplayer/types/events.d.ts @@ -14,6 +14,7 @@ export interface Events { '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] diff --git a/refactor/baselines/gesture-validation.json b/refactor/baselines/gesture-validation.json new file mode 100644 index 000000000..152779a6d --- /dev/null +++ b/refactor/baselines/gesture-validation.json @@ -0,0 +1,2218 @@ +{ + "task": "CORE-17", + "date": "2026-09-11", + "status": "partial", + "phase": "touch-gestures", + "parentCommit": "88aef830dfb583294ce29088d0ba92d9cf522d05", + "source": { + "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.js": "d6d2bd612daaf6c5c6e982158acbdf724b16d3c35bb5f1a5c923284665a8de79", + "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": "a02ab41654a963e06fb2eb206cfe606cebc27252ba00b3fc2116ea232c8d7d51", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "6856d98530877b9458275d8e064a94a81b9e2a4de079cce1a83e7cbe71e5ab8b", + "packages/artplayer/src/control/fullscreenWeb.ts": "e20f8fe9788738adfccb21e7bf248e5e8068312e856bb2626d05fbb20cfdb65d", + "packages/artplayer/src/control/index.ts": "ce23b79a0a40f22bdd8ad5f461d6b0df9366c7e4ab78571e0c67649f6e6d38e7", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "9299d785ce21b16dc9edbcb6a803f8748157ed16e1924f461bdbc4853adaa5ac", + "packages/artplayer/src/control/playAndPause.ts": "e65461f5bf29680f12b7e0efa7d44186f07bbe9936247a9a220f724c9d9774bb", + "packages/artplayer/src/control/progress/interactions.ts": "19d6f73c21f75daaef109247bee392d82b46fecffd04be0944386c307496b250", + "packages/artplayer/src/control/progress/position.ts": "6f96d79f1d3933076be2a78406a97935b7cd021c587ea429d0d10c67a4030811", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/progress.ts": "f0876ddbdc01f812a5a776bdeefdff8dc52e557aff684f99b5ea7f6bfc8c0fb3", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "430dc1b0283bc8a5c5396539b291dce1197470611696b32fde4b2c56d2db6b1f", + "packages/artplayer/src/control/selector.ts": "5d946c36d0308f32e08dd0e189f0c959f738ed7ab521230833c76a5bf9ca6478", + "packages/artplayer/src/control/setting.ts": "63e9824ffee2221ba82be9f2bc430b9b3133a2186905fcce2a61b8aa946a3d8a", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "7fab47c7106efa51aae89026af335f74d9f3ea52ef9864ec2801d0ea2deffc4c", + "packages/artplayer/src/control/volume.ts": "b50d1a5d2697d6440ac0f3d82634b13f7c2fff00c185a1adf4451ed8ba810709", + "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": "911207b0a3a9d4c2d0ef10b65ce7ace67e29e274fb922a8679fe818cf043d08c", + "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": "9dff7ee42c0cd1a9ab37a5acd9788b30ad01455bfd2f3abc2f4e1f157bf16c89", + "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/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "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.js": "39ac053f68e13a333ab778a62ca46b45478937a56cf32f1caeefedb510fb1bee", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "11342cb9c97c8ff728bbf6b47e58ce93a43062d4f69cf6cbbbc0a6f8d086c8fe", + "packages/artplayer/src/events/resizeInit.js": "26fc9628490e6c45ef741e7bc7c1353097b21da1dc83aae65dc80783226e36bc", + "packages/artplayer/src/events/updateInit.js": "1b4ef85c819ae68eb0de1791241b2c3d4e22bb108746518fa67f7c322591e55a", + "packages/artplayer/src/events/viewInit.js": "2b4ce508812b8f03cf5801a5e3a7eaa4a5a8b05d6be500d217aeb6231fb93a51", + "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": "3ef720aee403e6b7baf1ab472dbdd16c671f2d691ecea48ff1c25ca1ffc66296", + "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/index.js": "cb874ac34fa650bd364b3fef7eed4830bf3bd47093097ae7ba0432e7e64b1a10", + "packages/artplayer/src/info.js": "6dcdb4457d63ddb74fb6268df64522722420d6c0eb7b1654d6fb7703466d3b8c", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "2b6bec62d5f7468ea028a39914f9177cfbf96779f4b20274aa7e6b8784592764", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "30a4354e89f96a10bd15e3b94ce03050286d5cb4641b8f951fd17c0724afc238", + "packages/artplayer/src/input/keyboard-focus.ts": "9f49538e93c23e07a448a8f9c9773cbc2e199c6d86e7e0adb59236ce97a07fb5", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "ad542779ae4030c7619b5874fb33466cbd45af5ddb72d3ce984c09f54b24dccf", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "19a89de4ae22cb57eea7302265ce07422d12d1aea5acb99deb44fd0dba351a13", + "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.js": "4b08a8f9fa69f71d054cdf1508bbb9e92c075c8df1eda0fa8a79efbf08eb8c40", + "packages/artplayer/src/mask.js": "094162e28ec76c81f73bb7bfe276bf5832080ffb7aa9d9dc9dc013479659c2e5", + "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": "5532f57129032a9685305d0d319543146c3e8af134ac12c8aa521cca9e83a6c2", + "packages/artplayer/src/media/hosts.ts": "7129cb93290a250e932464b71a4e4abce8a98e83935d4fd6c36a59fc6357b6af", + "packages/artplayer/src/media/playback.ts": "b0e8ae22f2660249361bf05bb2333685e14f5a7ac3e9ba0c62ee7efd38338b93", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.js": "72e97833e0499993d8d133111e32f32f031b911426117397be2003e824023664", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.js": "b9ce49489e75045b6a1df4d8ed28f123c1b105ac4c04fefaabcffe4353ad004d", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.js": "c873d587ff71e024cfda5b5464d0c70a09a6a319da3f18fbaa7451a16c9ae055", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.js": "93e641dd760e8f844a643a0b7d8af92b73a7f205e55087d9501934d218701bd2", + "packages/artplayer/src/player/currentTimeMix.ts": "78c749ec4dc94f4a3a0ce02a87156f07894401b64d12c6c7c3cb1192ff266902", + "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.js": "c3eaeab0aa5015a51dfeeb4de6f25b02b8cd66e1f8471940367d628b5fd0bdec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.js": "9d1d9d276da2403a580498c62f947373e000d9cd6e4bef5831d272c3055b5592", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "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/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/posterMix.js": "a96b0a9f5817919e373a5a55b43fe7ea94af357051c01ddd6ce9c68bc932ecba", + "packages/artplayer/src/player/qualityMix.ts": "8dfcb94f695cf983f313f00abe1aec183ceb2af4b398fbf62bf1d114257a8f43", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.js": "c64871270b224233ea67ff31c3fbc0c2e2eb35635da5e4d5a263b930fb96e6e7", + "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.js": "382acfaf113fbd1ee77c63dba72953d984ea715f2d99748a12b9eae70c081d49", + "packages/artplayer/src/player/thumbnailsMix.js": "43bdbd9b62a803f4966103c6718305a9ef665d25df26f735d3e34558ddf339bf", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.js": "70920c8f785dca6d4bd66d82b996c37f1b69265190d7747ae8de298afae3604e", + "packages/artplayer/src/player/urlMix.ts": "23ee05577af66e3608f9c6d63f060bd3de68a99b1992e4e35e45f16a08a8c14f", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.js": "26f4a21691a2b2f767304b7d2fe40a35c599575651b9ace0c55a709a2be279b8", + "packages/artplayer/src/plugins/builtins.ts": "f4716e8db58a987c682dcd4d329f70a4a38196ee57100255955760cec924070d", + "packages/artplayer/src/plugins/fastForward.js": "d1f396efb22a279f9450fd02f85dc2245d274dbf0d36c99e87a5e5f895cc0029", + "packages/artplayer/src/plugins/index.ts": "28d13abc95cbedafadae0fdb682bf86fda9b705191c51843943a5dadddbd0a53", + "packages/artplayer/src/plugins/lock.js": "843caf8c7981463e8dadf1510cd028e7e70049f5a10038bd66dfccbc63bb7886", + "packages/artplayer/src/plugins/miniProgressBar.js": "3bf48d30c209105a0144c17062d6ea4e2bdd351b1bc928df73ea1680b78462e2", + "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": "2bb29994c60d0c47517bdf7cacb6afac7d65075f0a67d895a3ce52250b668232", + "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": "799e7adeac76c4a327201ec66f10d8f25f92387409f1e5e65f265df7711973e1", + "packages/artplayer/src/setting/update.ts": "3725fd69b369e4a345b1657ab559a915ab967c20088a093e288ffa7370cda264", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/switch.ts": "697ab56a765f957e3ce1da076c69cfc11dbf0901efecae0199cd94c729e0b236", + "packages/artplayer/src/source/types.ts": "9456d3d2f798188b730d99ef015e8a0a145598b0fe3ad1036b84f4a7cc1c5e6d", + "packages/artplayer/src/storage.js": "92067265b7f1104c4680e27e35726cf033811c6551e7c38d66028f2dd5300491", + "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": "ec67999b458d5545a4f17eeda922872823d655da012fa69113902629ad847548", + "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": "c8537df19c1d615419a8396db5846b4de05f61e61df8c0ed89613f0051b81e38", + "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": "743837b3c84fc5fee40120598bd484c10bd4202b371002709c269a700919dda2", + "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": "e56db829d7588f3a5dfafd6e8377f93f0892cfe442710be3740e1136812dd2bd", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "23f67e78ee43f9ad9099c94f28e51c6113b167603ffbbcf2d6ca2b68cc40b803", + "packages/artplayer/src/template.ts": "05c1499adc5dce27addf5761bec58d803f526d9b5b62c367c631e4cf2991391d", + "packages/artplayer/src/utils/compatibility.js": "51290838ef62be8e4251f4db8ecdd45a626cecd8c732e4e53a1c55df8d454a13", + "packages/artplayer/src/utils/component.ts": "d04a66213406ae3223326c2d470363e197dd1540519caa632f9d06378af989cc", + "packages/artplayer/src/utils/dom.js": "a625a0d832f717fbdf186099d1ace1f0dd51f1ea871417ffa856a7186206fb91", + "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" + }, + "artifacts": { + "packages/artplayer/dist/artplayer.js": "382ef085fe60c461676d30c3709be81d03453a513f699f4de53524fb5272df82", + "packages/artplayer/dist/artplayer.legacy.js": "3eb70817b55e20542b2dc644f05ec2cce0cffac9c2cfe056e4186bc777331385", + "packages/artplayer/dist/artplayer.mjs": "2f2c820d76239d133b58b2317724cd590ba2c4685b0e86453372a8f8dc4e89c4" + }, + "tests": { + "test/hotkey.test.js": "b647a4552ce43591f532d6295bf6d2034d7c301a2a9dae88cdb1b77e651ad5b5", + "test/types/hotkey.ts": "bc08aa59a8359a86e49cc95f880ae09d5c90a501d4d0ddae7d7467e90b042ef7", + "test/browser/hotkey.spec.js": "984e042d277da6ec092e5a16053bef0f2a144a83868dc30cee82a696c2adfeff", + "test/listener-registry.test.js": "07dcdb1945e530a3928b28a3758d22eca0db70bf4a00dd7e0527a56ef407c133", + "test/browser/listener-registry.spec.js": "54c40eebcd818342e92f875cb639d31d1fa0a0fc95897de2cbfbbd4df793ac94", + "test/global-events.test.js": "12494982e1846b6d6f6062eb209b7c1218c87a8b2ffb8342b5515ed91da2d337", + "test/browser/global-events.spec.js": "67ef2bc32419f17bb10ff40f7d9e542c110f2202028e5a17d58780e2cc6cf5f3", + "test/browser/lifecycle.spec.js": "7726535769bdf01a57d15d562bad9b3bb2cce0d979b7b0def6cbcf77bd72f453", + "test/browser/pointer-events.spec.js": "fa789898942d6eeffcb1f8867af46abcdb1dc8a515470ffdb18e89e8fafc4985", + "test/pointer-events.test.js": "8eccc6b72f025183cb93f1bbc2c03e42a98e1a3bdf6c03e8609c1b2fc9c2ea2d", + "test/gesture.test.js": "77235aa134d380a2bb39e572e41bd33b02f6c86ebe72426e55da4b00a5701f4e", + "test/types/gesture.ts": "3fb8fd3d895738443bedab2c00b1afda1009fcee5695555d25b73b9bcea61d8f", + "test/browser/gesture.spec.js": "9301a91220e5cccf1023918580111bf5287f811a51c0b51e7ed71797cb018575", + "test/browser/components.spec.js": "2be381b052b69baa3b4ae9cf2582593b9d611158e709e056aaa5df3cf969bef4", + "package.json": "90cacea0c3b97fb8841634c970a9dd91ec37a897fda0ccd065af402d1e3504c3" + }, + "ci": { + "passed": 312, + "unit": 283, + "engineering": 4, + "baseline": 25, + "strictSourceFiles": 180, + "logSha256": "c26e78b676429c31d79acd3ff855725097ad0d973556cdc65445ea92f407b9c3" + }, + "browser": { + "scope": "Hotkey, native listeners, global binding, lifecycle, pointer/gesture interaction and components only; workspace source, not final installed UMD/legacy acceptance", + "stats": { + "startTime": "2026-09-11T02:49:46.493Z", + "duration": 79885.901, + "expected": 303, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "candidateSha256": "dec85b1e79013892a1b421f45417e26c42487f5fb04db081d679e98e65054502", + "cases": [ + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed" + }, + { + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed" + }, + { + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed" + } + ], + "reportSha256": "e2d19341a6957fe320a5b6274e14fa1b2df533bc1a1a8072fde3b5b4bc64d28a" + }, + "baselines": [ + { + "file": "core17-listeners-baseline", + "stats": { + "startTime": "2026-09-11T02:01:57.051Z", + "duration": 13748.359, + "expected": 12, + "skipped": 0, + "unexpected": 12, + "flaky": 0 + }, + "reportSha256": "881fece2745d286782d4af78efb80f464b10d37a5aa25225d01b986c7408b1d7" + }, + { + "file": "core17-listeners-null-baseline", + "stats": { + "startTime": "2026-09-11T02:14:09.648Z", + "duration": 6851.293, + "expected": 3, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "8511bca0e86c3d01e8e58e42466ca2fdb5f92756c9d3235ef13f24ff08d52d7c" + }, + { + "file": "core17-global-baseline", + "stats": { + "startTime": "2026-09-11T02:15:57.255Z", + "duration": 9625.694000000001, + "expected": 9, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "37c86104c804f611cd7cb293c0e8d809ca7af5bb3f73493bce7b3c3b8ed7b7e9" + }, + { + "file": "refactor/.cache/core17-gesture-baseline.json", + "stats": { + "startTime": "2026-09-11T02:39:48.325Z", + "duration": 19404.032, + "expected": 21, + "skipped": 0, + "unexpected": 15, + "flaky": 0 + }, + "reportSha256": "67e9f7ec99e338831c1fb0239dbba7744dd99417bf0b445d276518ae4f6b2fc4", + "note": "Five candidate gesture invalidation/destruction targets failed in all three engines." + }, + { + "file": "refactor/.cache/core17-gesture-first.json", + "stats": { + "startTime": "2026-09-11T02:41:53.721Z", + "duration": 25491.372, + "expected": 52, + "skipped": 0, + "unexpected": 2, + "flaky": 0 + }, + "reportSha256": "dda794d81e3b097241a7bd858a0424faf33d9f366f42523d3e2bdb648e444ca2", + "note": "Two WebKit initial media positioning steps failed before gesture execution; subsequent tests initialize playback before positioning and separately cover pre-play requests." + } + ], + "build": { + "logSha256": "cb9a4b543c8918de9e9fd7d65347d7734a06899c4cdcb901c2776c3f0a69519b", + "i18nLogSha256": "09b745be7b113d4aff7ab0bcb1983376a5a081fcfc7bf936b0b4aa67c5e8e712" + }, + "remaining": [ + "Events facade migration", + "Resize/view/RAF scheduling and combined lifecycle checks", + "Full final installed UMD/legacy matrices and exact package consumers; CORE-17 remains doing", + "Physical-device certification remains a release gate; native once bookkeeping stays until explicit/owner cleanup" + ], + "publicTypes": { + "file": "packages/artplayer/types/events.d.ts", + "sha256": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "change": "Only the additive document:touchcancel Event entry; the remainder matches HEAD exactly." + } +} diff --git a/refactor/baselines/hotkey-validation.json b/refactor/baselines/hotkey-validation.json new file mode 100644 index 000000000..ce5ec1eae --- /dev/null +++ b/refactor/baselines/hotkey-validation.json @@ -0,0 +1,2430 @@ +{ + "task": "CORE-17", + "date": "2026-09-11", + "status": "partial", + "phase": "hotkey", + "parentCommit": "88aef830dfb583294ce29088d0ba92d9cf522d05", + "source": { + "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.js": "d6d2bd612daaf6c5c6e982158acbdf724b16d3c35bb5f1a5c923284665a8de79", + "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": "a02ab41654a963e06fb2eb206cfe606cebc27252ba00b3fc2116ea232c8d7d51", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "6856d98530877b9458275d8e064a94a81b9e2a4de079cce1a83e7cbe71e5ab8b", + "packages/artplayer/src/control/fullscreenWeb.ts": "e20f8fe9788738adfccb21e7bf248e5e8068312e856bb2626d05fbb20cfdb65d", + "packages/artplayer/src/control/index.ts": "ce23b79a0a40f22bdd8ad5f461d6b0df9366c7e4ab78571e0c67649f6e6d38e7", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "9299d785ce21b16dc9edbcb6a803f8748157ed16e1924f461bdbc4853adaa5ac", + "packages/artplayer/src/control/playAndPause.ts": "e65461f5bf29680f12b7e0efa7d44186f07bbe9936247a9a220f724c9d9774bb", + "packages/artplayer/src/control/progress/interactions.ts": "19d6f73c21f75daaef109247bee392d82b46fecffd04be0944386c307496b250", + "packages/artplayer/src/control/progress/position.ts": "1008c5129097cd2c51fefb56e88e9df6fa07f09ed5f4492505da9153d8284cd1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/progress.ts": "f0876ddbdc01f812a5a776bdeefdff8dc52e557aff684f99b5ea7f6bfc8c0fb3", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "430dc1b0283bc8a5c5396539b291dce1197470611696b32fde4b2c56d2db6b1f", + "packages/artplayer/src/control/selector.ts": "5d946c36d0308f32e08dd0e189f0c959f738ed7ab521230833c76a5bf9ca6478", + "packages/artplayer/src/control/setting.ts": "63e9824ffee2221ba82be9f2bc430b9b3133a2186905fcce2a61b8aa946a3d8a", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "7fab47c7106efa51aae89026af335f74d9f3ea52ef9864ec2801d0ea2deffc4c", + "packages/artplayer/src/control/volume.ts": "b50d1a5d2697d6440ac0f3d82634b13f7c2fff00c185a1adf4451ed8ba810709", + "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": "911207b0a3a9d4c2d0ef10b65ce7ace67e29e274fb922a8679fe818cf043d08c", + "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": "9dff7ee42c0cd1a9ab37a5acd9788b30ad01455bfd2f3abc2f4e1f157bf16c89", + "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/events/clickInit.js": "bc680c921a958c25705962577513677d5d97de94e4eff6a04ba20d2f60e6a1be", + "packages/artplayer/src/events/gestureInit.js": "a5dcdb4216c8e3544fc85a1b4d3ebd929ec6f7d51ab17f2cee713030ae7ad464", + "packages/artplayer/src/events/globalInit.js": "5d8c3147f17755b0d35504cfc69cf8cbff510b66b2a52686d8f2a235a6c5b9df", + "packages/artplayer/src/events/hoverInit.js": "7ed5666e01972dc0955d1c1b4006001c99dd55ed133ca026f685b71d6b4d01c6", + "packages/artplayer/src/events/index.js": "94ddb9ad5ceb21901fbbc974d983fec60c488314474c89138e4ab2b40e205d5a", + "packages/artplayer/src/events/moveInit.js": "782d627260c9fdf46c0766876138f05836860bc9c2fa2c519d22b43f3d24de15", + "packages/artplayer/src/events/resizeInit.js": "26fc9628490e6c45ef741e7bc7c1353097b21da1dc83aae65dc80783226e36bc", + "packages/artplayer/src/events/updateInit.js": "1b4ef85c819ae68eb0de1791241b2c3d4e22bb108746518fa67f7c322591e55a", + "packages/artplayer/src/events/viewInit.js": "2b4ce508812b8f03cf5801a5e3a7eaa4a5a8b05d6be500d217aeb6231fb93a51", + "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": "3ef720aee403e6b7baf1ab472dbdd16c671f2d691ecea48ff1c25ca1ffc66296", + "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/index.js": "cb874ac34fa650bd364b3fef7eed4830bf3bd47093097ae7ba0432e7e64b1a10", + "packages/artplayer/src/info.js": "6dcdb4457d63ddb74fb6268df64522722420d6c0eb7b1654d6fb7703466d3b8c", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "30a4354e89f96a10bd15e3b94ce03050286d5cb4641b8f951fd17c0724afc238", + "packages/artplayer/src/input/keyboard-focus.ts": "9f49538e93c23e07a448a8f9c9773cbc2e199c6d86e7e0adb59236ce97a07fb5", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "19a89de4ae22cb57eea7302265ce07422d12d1aea5acb99deb44fd0dba351a13", + "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.js": "4b08a8f9fa69f71d054cdf1508bbb9e92c075c8df1eda0fa8a79efbf08eb8c40", + "packages/artplayer/src/mask.js": "094162e28ec76c81f73bb7bfe276bf5832080ffb7aa9d9dc9dc013479659c2e5", + "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": "5532f57129032a9685305d0d319543146c3e8af134ac12c8aa521cca9e83a6c2", + "packages/artplayer/src/media/hosts.ts": "7129cb93290a250e932464b71a4e4abce8a98e83935d4fd6c36a59fc6357b6af", + "packages/artplayer/src/media/playback.ts": "b0e8ae22f2660249361bf05bb2333685e14f5a7ac3e9ba0c62ee7efd38338b93", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.js": "72e97833e0499993d8d133111e32f32f031b911426117397be2003e824023664", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.js": "b9ce49489e75045b6a1df4d8ed28f123c1b105ac4c04fefaabcffe4353ad004d", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.js": "c873d587ff71e024cfda5b5464d0c70a09a6a319da3f18fbaa7451a16c9ae055", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.js": "93e641dd760e8f844a643a0b7d8af92b73a7f205e55087d9501934d218701bd2", + "packages/artplayer/src/player/currentTimeMix.ts": "78c749ec4dc94f4a3a0ce02a87156f07894401b64d12c6c7c3cb1192ff266902", + "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.js": "c3eaeab0aa5015a51dfeeb4de6f25b02b8cd66e1f8471940367d628b5fd0bdec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.js": "9d1d9d276da2403a580498c62f947373e000d9cd6e4bef5831d272c3055b5592", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "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/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/posterMix.js": "a96b0a9f5817919e373a5a55b43fe7ea94af357051c01ddd6ce9c68bc932ecba", + "packages/artplayer/src/player/qualityMix.ts": "8dfcb94f695cf983f313f00abe1aec183ceb2af4b398fbf62bf1d114257a8f43", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.js": "c64871270b224233ea67ff31c3fbc0c2e2eb35635da5e4d5a263b930fb96e6e7", + "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.js": "382acfaf113fbd1ee77c63dba72953d984ea715f2d99748a12b9eae70c081d49", + "packages/artplayer/src/player/thumbnailsMix.js": "43bdbd9b62a803f4966103c6718305a9ef665d25df26f735d3e34558ddf339bf", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.js": "70920c8f785dca6d4bd66d82b996c37f1b69265190d7747ae8de298afae3604e", + "packages/artplayer/src/player/urlMix.ts": "23ee05577af66e3608f9c6d63f060bd3de68a99b1992e4e35e45f16a08a8c14f", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.js": "26f4a21691a2b2f767304b7d2fe40a35c599575651b9ace0c55a709a2be279b8", + "packages/artplayer/src/plugins/builtins.ts": "f4716e8db58a987c682dcd4d329f70a4a38196ee57100255955760cec924070d", + "packages/artplayer/src/plugins/fastForward.js": "d1f396efb22a279f9450fd02f85dc2245d274dbf0d36c99e87a5e5f895cc0029", + "packages/artplayer/src/plugins/index.ts": "28d13abc95cbedafadae0fdb682bf86fda9b705191c51843943a5dadddbd0a53", + "packages/artplayer/src/plugins/lock.js": "843caf8c7981463e8dadf1510cd028e7e70049f5a10038bd66dfccbc63bb7886", + "packages/artplayer/src/plugins/miniProgressBar.js": "3bf48d30c209105a0144c17062d6ea4e2bdd351b1bc928df73ea1680b78462e2", + "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": "2bb29994c60d0c47517bdf7cacb6afac7d65075f0a67d895a3ce52250b668232", + "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": "799e7adeac76c4a327201ec66f10d8f25f92387409f1e5e65f265df7711973e1", + "packages/artplayer/src/setting/update.ts": "3725fd69b369e4a345b1657ab559a915ab967c20088a093e288ffa7370cda264", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/switch.ts": "697ab56a765f957e3ce1da076c69cfc11dbf0901efecae0199cd94c729e0b236", + "packages/artplayer/src/source/types.ts": "9456d3d2f798188b730d99ef015e8a0a145598b0fe3ad1036b84f4a7cc1c5e6d", + "packages/artplayer/src/storage.js": "92067265b7f1104c4680e27e35726cf033811c6551e7c38d66028f2dd5300491", + "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": "ec67999b458d5545a4f17eeda922872823d655da012fa69113902629ad847548", + "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": "c8537df19c1d615419a8396db5846b4de05f61e61df8c0ed89613f0051b81e38", + "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": "743837b3c84fc5fee40120598bd484c10bd4202b371002709c269a700919dda2", + "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": "e56db829d7588f3a5dfafd6e8377f93f0892cfe442710be3740e1136812dd2bd", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "23f67e78ee43f9ad9099c94f28e51c6113b167603ffbbcf2d6ca2b68cc40b803", + "packages/artplayer/src/template.ts": "05c1499adc5dce27addf5761bec58d803f526d9b5b62c367c631e4cf2991391d", + "packages/artplayer/src/utils/compatibility.js": "51290838ef62be8e4251f4db8ecdd45a626cecd8c732e4e53a1c55df8d454a13", + "packages/artplayer/src/utils/component.ts": "d04a66213406ae3223326c2d470363e197dd1540519caa632f9d06378af989cc", + "packages/artplayer/src/utils/dom.js": "a625a0d832f717fbdf186099d1ace1f0dd51f1ea871417ffa856a7186206fb91", + "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" + }, + "artifacts": { + "packages/artplayer/dist/artplayer.js": "b056e1916e79417475800d4bc7c604c268a406558546b98e4ba69a5bcbed63cc", + "packages/artplayer/dist/artplayer.legacy.js": "fd1f3d55a7de9a6022d8a128134b28b3b0413cabfca37be206dea91cd132b4bc", + "packages/artplayer/dist/artplayer.mjs": "fd562634499eedde65c0f962a5c198157127581eda784eec71f8211fc5e5e51d" + }, + "tests": { + "test/hotkey.test.js": "b647a4552ce43591f532d6295bf6d2034d7c301a2a9dae88cdb1b77e651ad5b5", + "test/types/hotkey.ts": "bc08aa59a8359a86e49cc95f880ae09d5c90a501d4d0ddae7d7467e90b042ef7", + "test/browser/hotkey.spec.js": "2ecfdcab88816c34f9998e9bb85c98ab9b9725005cddab796d2e61b4b77b8034", + "package.json": "802ca37f5a0e4a35dbfa44c56a8a7654a81ffd7658e45bc1205391509aba9b9d" + }, + "ci": { + "passed": 278, + "unit": 249, + "engineering": 4, + "baseline": 25, + "strictSourceFiles": 168, + "logSha256": "d1005db6afd51a44f7b43033488c0fdfd586d86b2cfb1f798da5424286195fad" + }, + "browser": { + "scope": "Hotkey and display modes only, not the entire browser suite or installed artifact acceptance", + "stats": { + "startTime": "2026-09-11T01:54:56.313Z", + "duration": 114198.72, + "expected": 351, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "candidateSha256": "b23aaa12a572915a71f77b3b1171b1be4b0d4a8564b49c2d87465ff330a7f553", + "cases": [ + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "chromium", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "firefox", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed" + }, + { + "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" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed" + }, + { + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed" + } + ], + "reportSha256": "02a7329c791fd3b518c6273364eabcbb833f313371bf1e070d5b1ff62da48ee3" + }, + "baseline": { + "stats": { + "startTime": "2026-09-11T01:46:30.989Z", + "duration": 14644.398, + "expected": 15, + "skipped": 0, + "unexpected": 9, + "flaky": 0 + }, + "reportSha256": "41889dd9a28c2c1d75eefce35eb996f908fafe114ea88f60e00637767cae6a2a" + }, + "build": { + "logSha256": "2c736eb6a03ec449373ca9ab4ed0a028aab7dc9d88f1091eb06927fa1b229618", + "i18nLogSha256": "19db14931c231a8e206e22be1e214c1d86e6eb9333db6d700d977ba5824b54e9" + }, + "remaining": [ + "Events registration/global rebinding and partial failure lifecycle", + "Click, hover, move, gestures, resize/view/RAF and combined ownership", + "Full final installed UMD/legacy and package consumers; CORE-17 remains doing", + "IME and mobile UA tests are controlled, not physical-device certification" + ] +} diff --git a/refactor/baselines/input-listeners-validation.json b/refactor/baselines/input-listeners-validation.json new file mode 100644 index 000000000..6745efbc2 --- /dev/null +++ b/refactor/baselines/input-listeners-validation.json @@ -0,0 +1,1168 @@ +{ + "task": "CORE-17", + "date": "2026-09-11", + "status": "partial", + "phase": "native-listeners-and-global-binding", + "parentCommit": "88aef830dfb583294ce29088d0ba92d9cf522d05", + "source": { + "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.js": "d6d2bd612daaf6c5c6e982158acbdf724b16d3c35bb5f1a5c923284665a8de79", + "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": "a02ab41654a963e06fb2eb206cfe606cebc27252ba00b3fc2116ea232c8d7d51", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "6856d98530877b9458275d8e064a94a81b9e2a4de079cce1a83e7cbe71e5ab8b", + "packages/artplayer/src/control/fullscreenWeb.ts": "e20f8fe9788738adfccb21e7bf248e5e8068312e856bb2626d05fbb20cfdb65d", + "packages/artplayer/src/control/index.ts": "ce23b79a0a40f22bdd8ad5f461d6b0df9366c7e4ab78571e0c67649f6e6d38e7", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "9299d785ce21b16dc9edbcb6a803f8748157ed16e1924f461bdbc4853adaa5ac", + "packages/artplayer/src/control/playAndPause.ts": "e65461f5bf29680f12b7e0efa7d44186f07bbe9936247a9a220f724c9d9774bb", + "packages/artplayer/src/control/progress/interactions.ts": "19d6f73c21f75daaef109247bee392d82b46fecffd04be0944386c307496b250", + "packages/artplayer/src/control/progress/position.ts": "1008c5129097cd2c51fefb56e88e9df6fa07f09ed5f4492505da9153d8284cd1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/progress.ts": "f0876ddbdc01f812a5a776bdeefdff8dc52e557aff684f99b5ea7f6bfc8c0fb3", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "430dc1b0283bc8a5c5396539b291dce1197470611696b32fde4b2c56d2db6b1f", + "packages/artplayer/src/control/selector.ts": "5d946c36d0308f32e08dd0e189f0c959f738ed7ab521230833c76a5bf9ca6478", + "packages/artplayer/src/control/setting.ts": "63e9824ffee2221ba82be9f2bc430b9b3133a2186905fcce2a61b8aa946a3d8a", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "7fab47c7106efa51aae89026af335f74d9f3ea52ef9864ec2801d0ea2deffc4c", + "packages/artplayer/src/control/volume.ts": "b50d1a5d2697d6440ac0f3d82634b13f7c2fff00c185a1adf4451ed8ba810709", + "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": "911207b0a3a9d4c2d0ef10b65ce7ace67e29e274fb922a8679fe818cf043d08c", + "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": "9dff7ee42c0cd1a9ab37a5acd9788b30ad01455bfd2f3abc2f4e1f157bf16c89", + "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/events/clickInit.js": "bc680c921a958c25705962577513677d5d97de94e4eff6a04ba20d2f60e6a1be", + "packages/artplayer/src/events/gestureInit.js": "a5dcdb4216c8e3544fc85a1b4d3ebd929ec6f7d51ab17f2cee713030ae7ad464", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "1d57f919a8b9e35a935846f7243b8a84e636f0f5e255e27062b1084c36555c61", + "packages/artplayer/src/events/hoverInit.js": "7ed5666e01972dc0955d1c1b4006001c99dd55ed133ca026f685b71d6b4d01c6", + "packages/artplayer/src/events/index.js": "39ac053f68e13a333ab778a62ca46b45478937a56cf32f1caeefedb510fb1bee", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.js": "782d627260c9fdf46c0766876138f05836860bc9c2fa2c519d22b43f3d24de15", + "packages/artplayer/src/events/resizeInit.js": "26fc9628490e6c45ef741e7bc7c1353097b21da1dc83aae65dc80783226e36bc", + "packages/artplayer/src/events/updateInit.js": "1b4ef85c819ae68eb0de1791241b2c3d4e22bb108746518fa67f7c322591e55a", + "packages/artplayer/src/events/viewInit.js": "2b4ce508812b8f03cf5801a5e3a7eaa4a5a8b05d6be500d217aeb6231fb93a51", + "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": "3ef720aee403e6b7baf1ab472dbdd16c671f2d691ecea48ff1c25ca1ffc66296", + "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/index.js": "cb874ac34fa650bd364b3fef7eed4830bf3bd47093097ae7ba0432e7e64b1a10", + "packages/artplayer/src/info.js": "6dcdb4457d63ddb74fb6268df64522722420d6c0eb7b1654d6fb7703466d3b8c", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "30a4354e89f96a10bd15e3b94ce03050286d5cb4641b8f951fd17c0724afc238", + "packages/artplayer/src/input/keyboard-focus.ts": "9f49538e93c23e07a448a8f9c9773cbc2e199c6d86e7e0adb59236ce97a07fb5", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "19a89de4ae22cb57eea7302265ce07422d12d1aea5acb99deb44fd0dba351a13", + "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.js": "4b08a8f9fa69f71d054cdf1508bbb9e92c075c8df1eda0fa8a79efbf08eb8c40", + "packages/artplayer/src/mask.js": "094162e28ec76c81f73bb7bfe276bf5832080ffb7aa9d9dc9dc013479659c2e5", + "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": "5532f57129032a9685305d0d319543146c3e8af134ac12c8aa521cca9e83a6c2", + "packages/artplayer/src/media/hosts.ts": "7129cb93290a250e932464b71a4e4abce8a98e83935d4fd6c36a59fc6357b6af", + "packages/artplayer/src/media/playback.ts": "b0e8ae22f2660249361bf05bb2333685e14f5a7ac3e9ba0c62ee7efd38338b93", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.js": "72e97833e0499993d8d133111e32f32f031b911426117397be2003e824023664", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.js": "b9ce49489e75045b6a1df4d8ed28f123c1b105ac4c04fefaabcffe4353ad004d", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.js": "c873d587ff71e024cfda5b5464d0c70a09a6a319da3f18fbaa7451a16c9ae055", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.js": "93e641dd760e8f844a643a0b7d8af92b73a7f205e55087d9501934d218701bd2", + "packages/artplayer/src/player/currentTimeMix.ts": "78c749ec4dc94f4a3a0ce02a87156f07894401b64d12c6c7c3cb1192ff266902", + "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.js": "c3eaeab0aa5015a51dfeeb4de6f25b02b8cd66e1f8471940367d628b5fd0bdec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.js": "9d1d9d276da2403a580498c62f947373e000d9cd6e4bef5831d272c3055b5592", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "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/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/posterMix.js": "a96b0a9f5817919e373a5a55b43fe7ea94af357051c01ddd6ce9c68bc932ecba", + "packages/artplayer/src/player/qualityMix.ts": "8dfcb94f695cf983f313f00abe1aec183ceb2af4b398fbf62bf1d114257a8f43", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.js": "c64871270b224233ea67ff31c3fbc0c2e2eb35635da5e4d5a263b930fb96e6e7", + "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.js": "382acfaf113fbd1ee77c63dba72953d984ea715f2d99748a12b9eae70c081d49", + "packages/artplayer/src/player/thumbnailsMix.js": "43bdbd9b62a803f4966103c6718305a9ef665d25df26f735d3e34558ddf339bf", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.js": "70920c8f785dca6d4bd66d82b996c37f1b69265190d7747ae8de298afae3604e", + "packages/artplayer/src/player/urlMix.ts": "23ee05577af66e3608f9c6d63f060bd3de68a99b1992e4e35e45f16a08a8c14f", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.js": "26f4a21691a2b2f767304b7d2fe40a35c599575651b9ace0c55a709a2be279b8", + "packages/artplayer/src/plugins/builtins.ts": "f4716e8db58a987c682dcd4d329f70a4a38196ee57100255955760cec924070d", + "packages/artplayer/src/plugins/fastForward.js": "d1f396efb22a279f9450fd02f85dc2245d274dbf0d36c99e87a5e5f895cc0029", + "packages/artplayer/src/plugins/index.ts": "28d13abc95cbedafadae0fdb682bf86fda9b705191c51843943a5dadddbd0a53", + "packages/artplayer/src/plugins/lock.js": "843caf8c7981463e8dadf1510cd028e7e70049f5a10038bd66dfccbc63bb7886", + "packages/artplayer/src/plugins/miniProgressBar.js": "3bf48d30c209105a0144c17062d6ea4e2bdd351b1bc928df73ea1680b78462e2", + "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": "2bb29994c60d0c47517bdf7cacb6afac7d65075f0a67d895a3ce52250b668232", + "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": "799e7adeac76c4a327201ec66f10d8f25f92387409f1e5e65f265df7711973e1", + "packages/artplayer/src/setting/update.ts": "3725fd69b369e4a345b1657ab559a915ab967c20088a093e288ffa7370cda264", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/switch.ts": "697ab56a765f957e3ce1da076c69cfc11dbf0901efecae0199cd94c729e0b236", + "packages/artplayer/src/source/types.ts": "9456d3d2f798188b730d99ef015e8a0a145598b0fe3ad1036b84f4a7cc1c5e6d", + "packages/artplayer/src/storage.js": "92067265b7f1104c4680e27e35726cf033811c6551e7c38d66028f2dd5300491", + "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": "ec67999b458d5545a4f17eeda922872823d655da012fa69113902629ad847548", + "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": "c8537df19c1d615419a8396db5846b4de05f61e61df8c0ed89613f0051b81e38", + "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": "743837b3c84fc5fee40120598bd484c10bd4202b371002709c269a700919dda2", + "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": "e56db829d7588f3a5dfafd6e8377f93f0892cfe442710be3740e1136812dd2bd", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "23f67e78ee43f9ad9099c94f28e51c6113b167603ffbbcf2d6ca2b68cc40b803", + "packages/artplayer/src/template.ts": "05c1499adc5dce27addf5761bec58d803f526d9b5b62c367c631e4cf2991391d", + "packages/artplayer/src/utils/compatibility.js": "51290838ef62be8e4251f4db8ecdd45a626cecd8c732e4e53a1c55df8d454a13", + "packages/artplayer/src/utils/component.ts": "d04a66213406ae3223326c2d470363e197dd1540519caa632f9d06378af989cc", + "packages/artplayer/src/utils/dom.js": "a625a0d832f717fbdf186099d1ace1f0dd51f1ea871417ffa856a7186206fb91", + "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" + }, + "artifacts": { + "packages/artplayer/dist/artplayer.js": "6bab31cd47d32b39866c455909d15bd72ed9ab9630944e87fef6976c0b906e26", + "packages/artplayer/dist/artplayer.legacy.js": "f531b32d646803b8c3aa651aac476efd09fa6d0f28f4cc1d1ab49d13da5f97be", + "packages/artplayer/dist/artplayer.mjs": "cecbf3358aa8cf04727843cf0a9c35fbef168a830dedbb43a72a738daf72cee4" + }, + "tests": { + "test/hotkey.test.js": "b647a4552ce43591f532d6295bf6d2034d7c301a2a9dae88cdb1b77e651ad5b5", + "test/types/hotkey.ts": "bc08aa59a8359a86e49cc95f880ae09d5c90a501d4d0ddae7d7467e90b042ef7", + "test/browser/hotkey.spec.js": "2ecfdcab88816c34f9998e9bb85c98ab9b9725005cddab796d2e61b4b77b8034", + "test/listener-registry.test.js": "07dcdb1945e530a3928b28a3758d22eca0db70bf4a00dd7e0527a56ef407c133", + "test/browser/listener-registry.spec.js": "54c40eebcd818342e92f875cb639d31d1fa0a0fc95897de2cbfbbd4df793ac94", + "test/global-events.test.js": "ab57213ce56ddf7139c3b045915a6d5c5e6e7aaf84075e656c02a0d8a61b3ffc", + "test/browser/global-events.spec.js": "67ef2bc32419f17bb10ff40f7d9e542c110f2202028e5a17d58780e2cc6cf5f3", + "test/browser/lifecycle.spec.js": "7726535769bdf01a57d15d562bad9b3bb2cce0d979b7b0def6cbcf77bd72f453", + "package.json": "9430a259970cfbf697613ca7642c84a02a74acb191624244c2e46ed02fd70a6d" + }, + "ci": { + "passed": 292, + "unit": 263, + "engineering": 4, + "baseline": 25, + "strictSourceFiles": 171, + "logSha256": "b982cc5ecf2d9b36c94cc95b06b952406575f05e6aca064c93241daba3df7bd7" + }, + "browser": { + "scope": "Hotkey, native listeners, global binding and lifecycle only; workspace source, not final installed UMD/legacy acceptance", + "stats": { + "startTime": "2026-09-11T02:20:11.500Z", + "duration": 38274.027, + "expected": 135, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "candidateSha256": "9e9986257710bc4bf47d57e547e364b31e948b3f71c12a4bb572890fc8c38033", + "cases": [ + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed" + } + ], + "reportSha256": "557cb01acd778f8491c817634db394d8dd14f3e7a0861b3c8ac96d2dbf9c238d" + }, + "baselines": [ + { + "file": "core17-listeners-baseline", + "stats": { + "startTime": "2026-09-11T02:01:57.051Z", + "duration": 13748.359, + "expected": 12, + "skipped": 0, + "unexpected": 12, + "flaky": 0 + }, + "reportSha256": "881fece2745d286782d4af78efb80f464b10d37a5aa25225d01b986c7408b1d7" + }, + { + "file": "core17-listeners-null-baseline", + "stats": { + "startTime": "2026-09-11T02:14:09.648Z", + "duration": 6851.293, + "expected": 3, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "8511bca0e86c3d01e8e58e42466ca2fdb5f92756c9d3235ef13f24ff08d52d7c" + }, + { + "file": "core17-global-baseline", + "stats": { + "startTime": "2026-09-11T02:15:57.255Z", + "duration": 9625.694000000001, + "expected": 9, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "37c86104c804f611cd7cb293c0e8d809ca7af5bb3f73493bce7b3c3b8ed7b7e9" + } + ], + "build": { + "logSha256": "61b4fefc06782f374f66a65047fccad812a19ab42d05fbadefa51dce157ee8ee", + "i18nLogSha256": "5e2ebcc53bd4dde736b685a0b58292d40123fea82213b16010d4093352d9df2a" + }, + "remaining": [ + "Events facade and click/hover/move/gesture migration", + "Resize/view/RAF scheduling and combined lifecycle checks", + "Full final installed UMD/legacy matrices and exact package consumers; CORE-17 remains doing", + "Physical-device certification remains a release gate; native once bookkeeping stays until explicit/owner cleanup" + ] +} diff --git a/refactor/baselines/input-validation.json b/refactor/baselines/input-validation.json new file mode 100644 index 000000000..9e9dc842f --- /dev/null +++ b/refactor/baselines/input-validation.json @@ -0,0 +1,19176 @@ +{ + "task": "CORE-17", + "date": "2026-09-11", + "status": "validated", + "node": "v24.21.0", + "parentCommit": "88aef830dfb583294ce29088d0ba92d9cf522d05", + "source": { + "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.js": "d6d2bd612daaf6c5c6e982158acbdf724b16d3c35bb5f1a5c923284665a8de79", + "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": "a02ab41654a963e06fb2eb206cfe606cebc27252ba00b3fc2116ea232c8d7d51", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "6856d98530877b9458275d8e064a94a81b9e2a4de079cce1a83e7cbe71e5ab8b", + "packages/artplayer/src/control/fullscreenWeb.ts": "e20f8fe9788738adfccb21e7bf248e5e8068312e856bb2626d05fbb20cfdb65d", + "packages/artplayer/src/control/index.ts": "ce23b79a0a40f22bdd8ad5f461d6b0df9366c7e4ab78571e0c67649f6e6d38e7", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "9299d785ce21b16dc9edbcb6a803f8748157ed16e1924f461bdbc4853adaa5ac", + "packages/artplayer/src/control/playAndPause.ts": "e65461f5bf29680f12b7e0efa7d44186f07bbe9936247a9a220f724c9d9774bb", + "packages/artplayer/src/control/progress/interactions.ts": "19d6f73c21f75daaef109247bee392d82b46fecffd04be0944386c307496b250", + "packages/artplayer/src/control/progress/position.ts": "6f96d79f1d3933076be2a78406a97935b7cd021c587ea429d0d10c67a4030811", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/progress.ts": "f0876ddbdc01f812a5a776bdeefdff8dc52e557aff684f99b5ea7f6bfc8c0fb3", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "430dc1b0283bc8a5c5396539b291dce1197470611696b32fde4b2c56d2db6b1f", + "packages/artplayer/src/control/selector.ts": "5d946c36d0308f32e08dd0e189f0c959f738ed7ab521230833c76a5bf9ca6478", + "packages/artplayer/src/control/setting.ts": "63e9824ffee2221ba82be9f2bc430b9b3133a2186905fcce2a61b8aa946a3d8a", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "7fab47c7106efa51aae89026af335f74d9f3ea52ef9864ec2801d0ea2deffc4c", + "packages/artplayer/src/control/volume.ts": "b50d1a5d2697d6440ac0f3d82634b13f7c2fff00c185a1adf4451ed8ba810709", + "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": "911207b0a3a9d4c2d0ef10b65ce7ace67e29e274fb922a8679fe818cf043d08c", + "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": "9dff7ee42c0cd1a9ab37a5acd9788b30ad01455bfd2f3abc2f4e1f157bf16c89", + "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/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "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": "11342cb9c97c8ff728bbf6b47e58ce93a43062d4f69cf6cbbbc0a6f8d086c8fe", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "5cfeb1bfc23b06bf71c8049bd2cc2f5de384840a2b16511d1222944b0ccd4684", + "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": "3ef720aee403e6b7baf1ab472dbdd16c671f2d691ecea48ff1c25ca1ffc66296", + "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/index.js": "cb874ac34fa650bd364b3fef7eed4830bf3bd47093097ae7ba0432e7e64b1a10", + "packages/artplayer/src/info.js": "6dcdb4457d63ddb74fb6268df64522722420d6c0eb7b1654d6fb7703466d3b8c", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "2b6bec62d5f7468ea028a39914f9177cfbf96779f4b20274aa7e6b8784592764", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "30a4354e89f96a10bd15e3b94ce03050286d5cb4641b8f951fd17c0724afc238", + "packages/artplayer/src/input/keyboard-focus.ts": "9f49538e93c23e07a448a8f9c9773cbc2e199c6d86e7e0adb59236ce97a07fb5", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "ad542779ae4030c7619b5874fb33466cbd45af5ddb72d3ce984c09f54b24dccf", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "19a89de4ae22cb57eea7302265ce07422d12d1aea5acb99deb44fd0dba351a13", + "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.js": "4b08a8f9fa69f71d054cdf1508bbb9e92c075c8df1eda0fa8a79efbf08eb8c40", + "packages/artplayer/src/mask.js": "094162e28ec76c81f73bb7bfe276bf5832080ffb7aa9d9dc9dc013479659c2e5", + "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": "5532f57129032a9685305d0d319543146c3e8af134ac12c8aa521cca9e83a6c2", + "packages/artplayer/src/media/hosts.ts": "7129cb93290a250e932464b71a4e4abce8a98e83935d4fd6c36a59fc6357b6af", + "packages/artplayer/src/media/playback.ts": "b0e8ae22f2660249361bf05bb2333685e14f5a7ac3e9ba0c62ee7efd38338b93", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.js": "72e97833e0499993d8d133111e32f32f031b911426117397be2003e824023664", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.js": "b9ce49489e75045b6a1df4d8ed28f123c1b105ac4c04fefaabcffe4353ad004d", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.js": "c873d587ff71e024cfda5b5464d0c70a09a6a319da3f18fbaa7451a16c9ae055", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.js": "93e641dd760e8f844a643a0b7d8af92b73a7f205e55087d9501934d218701bd2", + "packages/artplayer/src/player/currentTimeMix.ts": "78c749ec4dc94f4a3a0ce02a87156f07894401b64d12c6c7c3cb1192ff266902", + "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.js": "c3eaeab0aa5015a51dfeeb4de6f25b02b8cd66e1f8471940367d628b5fd0bdec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.js": "9d1d9d276da2403a580498c62f947373e000d9cd6e4bef5831d272c3055b5592", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "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/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/posterMix.js": "a96b0a9f5817919e373a5a55b43fe7ea94af357051c01ddd6ce9c68bc932ecba", + "packages/artplayer/src/player/qualityMix.ts": "8dfcb94f695cf983f313f00abe1aec183ceb2af4b398fbf62bf1d114257a8f43", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.js": "c64871270b224233ea67ff31c3fbc0c2e2eb35635da5e4d5a263b930fb96e6e7", + "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.js": "382acfaf113fbd1ee77c63dba72953d984ea715f2d99748a12b9eae70c081d49", + "packages/artplayer/src/player/thumbnailsMix.js": "43bdbd9b62a803f4966103c6718305a9ef665d25df26f735d3e34558ddf339bf", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.js": "70920c8f785dca6d4bd66d82b996c37f1b69265190d7747ae8de298afae3604e", + "packages/artplayer/src/player/urlMix.ts": "23ee05577af66e3608f9c6d63f060bd3de68a99b1992e4e35e45f16a08a8c14f", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.js": "26f4a21691a2b2f767304b7d2fe40a35c599575651b9ace0c55a709a2be279b8", + "packages/artplayer/src/plugins/builtins.ts": "f4716e8db58a987c682dcd4d329f70a4a38196ee57100255955760cec924070d", + "packages/artplayer/src/plugins/fastForward.js": "d1f396efb22a279f9450fd02f85dc2245d274dbf0d36c99e87a5e5f895cc0029", + "packages/artplayer/src/plugins/index.ts": "28d13abc95cbedafadae0fdb682bf86fda9b705191c51843943a5dadddbd0a53", + "packages/artplayer/src/plugins/lock.js": "843caf8c7981463e8dadf1510cd028e7e70049f5a10038bd66dfccbc63bb7886", + "packages/artplayer/src/plugins/miniProgressBar.js": "3bf48d30c209105a0144c17062d6ea4e2bdd351b1bc928df73ea1680b78462e2", + "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": "2bb29994c60d0c47517bdf7cacb6afac7d65075f0a67d895a3ce52250b668232", + "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": "799e7adeac76c4a327201ec66f10d8f25f92387409f1e5e65f265df7711973e1", + "packages/artplayer/src/setting/update.ts": "3725fd69b369e4a345b1657ab559a915ab967c20088a093e288ffa7370cda264", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/switch.ts": "697ab56a765f957e3ce1da076c69cfc11dbf0901efecae0199cd94c729e0b236", + "packages/artplayer/src/source/types.ts": "9456d3d2f798188b730d99ef015e8a0a145598b0fe3ad1036b84f4a7cc1c5e6d", + "packages/artplayer/src/storage.js": "92067265b7f1104c4680e27e35726cf033811c6551e7c38d66028f2dd5300491", + "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": "ec67999b458d5545a4f17eeda922872823d655da012fa69113902629ad847548", + "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": "c8537df19c1d615419a8396db5846b4de05f61e61df8c0ed89613f0051b81e38", + "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": "743837b3c84fc5fee40120598bd484c10bd4202b371002709c269a700919dda2", + "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": "e56db829d7588f3a5dfafd6e8377f93f0892cfe442710be3740e1136812dd2bd", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "23f67e78ee43f9ad9099c94f28e51c6113b167603ffbbcf2d6ca2b68cc40b803", + "packages/artplayer/src/template.ts": "05c1499adc5dce27addf5761bec58d803f526d9b5b62c367c631e4cf2991391d", + "packages/artplayer/src/utils/compatibility.js": "51290838ef62be8e4251f4db8ecdd45a626cecd8c732e4e53a1c55df8d454a13", + "packages/artplayer/src/utils/component.ts": "d04a66213406ae3223326c2d470363e197dd1540519caa632f9d06378af989cc", + "packages/artplayer/src/utils/dom.js": "a625a0d832f717fbdf186099d1ace1f0dd51f1ea871417ffa856a7186206fb91", + "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" + }, + "tests": { + "package.json": "2d1d7d9995c25879efd71f5fdbb524bd150e4c58b75c4e1a2877fd55b2873e66", + "test/event-scheduling.test.js": "65faab59cef6223140808bc310871853610fe3944ea0ab882173037726ddc258", + "test/gesture.test.js": "77235aa134d380a2bb39e572e41bd33b02f6c86ebe72426e55da4b00a5701f4e", + "test/global-events.test.js": "12494982e1846b6d6f6062eb209b7c1218c87a8b2ffb8342b5515ed91da2d337", + "test/hotkey.test.js": "b647a4552ce43591f532d6295bf6d2034d7c301a2a9dae88cdb1b77e651ad5b5", + "test/listener-registry.test.js": "07dcdb1945e530a3928b28a3758d22eca0db70bf4a00dd7e0527a56ef407c133", + "test/pointer-events.test.js": "8eccc6b72f025183cb93f1bbc2c03e42a98e1a3bdf6c03e8609c1b2fc9c2ea2d", + "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/emitter.spec.js": "abf5a850835d1a5580d611a0777c0cdf225a6aa796a63b58096f8646007e5870", + "test/browser/event-scheduling.spec.js": "4ebd5dab23ca8e49580bd1dc3234e612cbae36b735c7c9401d168059eae11c5c", + "test/browser/gesture.spec.js": "9301a91220e5cccf1023918580111bf5287f811a51c0b51e7ed71797cb018575", + "test/browser/global-events.spec.js": "67ef2bc32419f17bb10ff40f7d9e542c110f2202028e5a17d58780e2cc6cf5f3", + "test/browser/hotkey.spec.js": "984e042d277da6ec092e5a16053bef0f2a144a83868dc30cee82a696c2adfeff", + "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/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/resource-scope.spec.js": "0196bd9943c1ce2f6560f87156cd0de47606579c1a736bd46d4943179a121d3f", + "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": "0e6a9396e329bbd055afe14da2e029c08881d09454aa58c8711476a690a44c14", + "test/browser/subtitle-lifecycle.spec.js": "ba91719ccdc9e539aee252d80deaba622fd6e5cb30cdd74697658af1e49dfd58", + "test/browser/template-resources.spec.js": "993ce9876ae9d49f291af4173ffa34276f9b8972828e8d42b8789c5ee512ac6d", + "test/browser/utils.spec.js": "e7f1739938791a6d19ec2cdf544f57c69ad7caaaa6f379128b3676d73d8611b1", + "test/types/events-source.ts": "504d33f54d995c245ea759a08ec55085f38f22707c39e45d26ddfdce261911f5", + "test/types/gesture.ts": "3fb8fd3d895738443bedab2c00b1afda1009fcee5695555d25b73b9bcea61d8f", + "test/types/hotkey.ts": "bc08aa59a8359a86e49cc95f880ae09d5c90a501d4d0ddae7d7467e90b042ef7" + }, + "ci": { + "command": "yarn ci:check", + "passed": 321, + "unit": 292, + "engineering": 4, + "baseline": 25, + "strictSourceFiles": 188, + "logSha256": "1b5aa5cd53f12e0bc83e8e74893db2a53bcda9903e18fdc47b6d7ae0ac6063e5" + }, + "packageOutput": "refactor/.cache/packages/run-XOwSyu", + "packages": [ + { + "name": "artplayer", + "version": "5.4.1", + "archive": "artplayer.tgz", + "sha256": "f53e6749c4a4d2d0a6fc48a9de2abd1665d39cc07080acdffda77f2f02a29097", + "files": { + "package/ARCHITECTURE.md": "12fa0993a904cd7c3f260a9603113e6da992e11c193c74ef9d2a954215fccd9c", + "package/README.md": "1e185e65f67fc2081b4182bbc6c4558ea05b6e3fa3acc5dd0c3ac7df1d542b09", + "package/THIRD_PARTY_NOTICES": "b77b5b46b79fa0cda850b0781f78c3b1112c4ed9672fa291956fe8eff53098e7", + "package/dist/artplayer.js": "c768d111782b102062dff1eb75320bd99404efc59956445e7c95d598c90d0659", + "package/dist/artplayer.legacy.js": "11144499ad0c37ee1b2719992d9e9836b7d5b5abd7b37f6aa4928aaba05cc924", + "package/dist/artplayer.mjs": "8082a59476c167494b1fc7d7a570c34cda837c92d749a67a2c2520a96c205ab0", + "package/dist/i18n/ar.js": "5885c469efc9f07aafd6a4aa6698edae2c2683f42497ebbe15374130f9b6e2c7", + "package/dist/i18n/ar.mjs": "a275cf39ae2317ea1cea73b65ba5451a909b34a881d35920391cef2ff0d6a86f", + "package/dist/i18n/cs.js": "5adef10fadb219948eb5e58e204207ca0afdd2dd941a08d9455fd302ef2447cc", + "package/dist/i18n/cs.mjs": "2d274b61c2be9a472a3cc19dfa775e6209867f8d1d5a9116923f075446f47969", + "package/dist/i18n/es.js": "4c6662edce1398d0fe285978df83b271cce23e4f24e0e6a9d24a5b8a6845839b", + "package/dist/i18n/es.mjs": "09c0806a979feb4ae0e3ff32dbee9fd435847d3a66f80b6768ff69ab63289696", + "package/dist/i18n/fa.js": "db37cade9454df0b829c514e088d4d9175199faaff2b4a7838e6a401741131fe", + "package/dist/i18n/fa.mjs": "83290582155ee2a7a08a8c9cf8c2903545e78260e81a2a091092f3fbe61b4dd0", + "package/dist/i18n/fr.js": "54eee11fdf245e9882cb1f440f8909ccb8112f2e10722447cb313cab4752abea", + "package/dist/i18n/fr.mjs": "621844a04365da3d9e5d225d64e233d322cb9fd9c1ffcc2db77e5d7e0e78ea8e", + "package/dist/i18n/id.js": "5d4ee91a123c417b5b2e84890d85f416444389bdcd12c40d49073e1061796463", + "package/dist/i18n/id.mjs": "ffca08de9515704ef160dd902534df4b4113ff3f62b37f70330264d27daf5c34", + "package/dist/i18n/pl.js": "47e0d39623896436722439c758488ec660752c56a0294375bf0fce4f3b2aa27b", + "package/dist/i18n/pl.mjs": "05fbb3b2d09b44b5d3a237ea35a1f6865d45c2985e32b517dec4a00670cddebc", + "package/dist/i18n/ru.js": "3af3b15b1554579352b9b1ecfc8ac27abb584a5af9bcc7a8369a813c55df8834", + "package/dist/i18n/ru.mjs": "12281df03fc45c40ab8ad2a7dd8bbbab35f086dadd7e51f35e27826fff16e1ce", + "package/dist/i18n/tr.js": "0f8da88d4f770d9ec2e83311bbd6cc6ecfc0b2bbb3997f8db8eea8b795746967", + "package/dist/i18n/tr.mjs": "ea533927a7f32b3124177e87d9d5adbd279dc80efca7b11ad94696b3b47f7e94", + "package/dist/i18n/vi.js": "e3302f5c90f3e7df4bf8667c17598d0e46b66b31aab0d94fa70f3e617b5277c0", + "package/dist/i18n/vi.mjs": "f7a0ce8d821bff93354be31922a73be854a685e14170e8875cd5375f155e8737", + "package/dist/i18n/zh-tw.js": "13446c81dccf57e6b5d2be0a55b8ef6a668c6b8005ef4a497439557d6ccb16ec", + "package/dist/i18n/zh-tw.mjs": "730ae246aef8cffb34d7ba3b48aefab38fa812cf84ea7ebbd827f8639ee7eba7", + "package/package.json": "38fa5a41fe142c34ba52ce4ecd7cc81f25a7aba5adbe9e8fab843caedbddc15c", + "package/types/COMPATIBILITY.md": "72f619eb708e18040d12e0fbc5ce79f80bb22967687fa0d5afae6f2c6eae6d00", + "package/types/README.md": "93438f6009fc8017147ff4293e78849c102acce9aecc3d196ff135151081ff27", + "package/types/artplayer.d.cts": "a40ac7abd689b270e95eb0c3b70d67e1897b422d3d85d68f59173936bf80c332", + "package/types/artplayer.d.mts": "f6292596a9ccb1d43a6d6a12c35f859b1889ad15924c5ae0f9f280941aade313", + "package/types/artplayer.d.ts": "b57d9ac0a6f7a0215288ea286fedaf73043ac15557a3d82fc4b905f6d006f092", + "package/types/component.d.ts": "aa1c43be67322781b4b355b143bc69d9f29d22e578e4974d6a13e957a7c0334f", + "package/types/config.d.ts": "c4fd8681bf32b10c743e3e561c532520c8f32e43fd765524850b15e55cb91c72", + "package/types/cssVar.d.ts": "e027d82fb4f01c9ce7559cf679b2d5ee1962d3f7e5b4dd64ca21f472b933efb6", + "package/types/emitter.d.ts": "9c62551cdcc6dd3966bed8a7a85dd477435db977c91a294d2ac8f162f9592537", + "package/types/events.d.ts": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "package/types/i18n.d.ts": "3e14759caf71f97f01650839248c8737c42d2c2979dabc43ad92b724da648708", + "package/types/icons.d.ts": "0d8e8e52e52130dd4a29bab551dd7a2a954797e42e92a6e068c85d583e23e6a4", + "package/types/language.d.cts": "1c9e0c47fae3c2d68c3e144d95a55071318a03bb31554dd049109efd3d0f95a4", + "package/types/language.d.mts": "c391e863012c77769e661afbf8fa949e9373aa88d17f58cbba7f5696edb8077f", + "package/types/legacy/language.d.ts": "c452ffd764ff9b29b819b3475c42395d2ea7a33560d8c186ef5df3844b9524c3", + "package/types/option.d.ts": "850e5264219b8b438c80694402225b690b131786677a5da0d22739ec2352d263", + "package/types/playback.d.ts": "1ceaed3aa1cef511fe8b20f4874647f6065c723ad805b742a0a9247e16bb1bb5", + "package/types/player.d.ts": "f1e50257df2ea592d0a0e1f36078dda77eaf2cf3b3d795307501396562d99f28", + "package/types/plugin.d.ts": "2a57e148fda00ee687da5036b890b0f611cb94bb403a1ed52602179060259d35", + "package/types/quality.d.ts": "7ed6ed78cea52991b2f6ddd2bd3b7bd8c5146fdfff7486fe8b814c3e632f1567", + "package/types/setting.d.ts": "d12a75b656fff70cbb30be4bffec46d9c4273636e8722bce971a4d2b188712a1", + "package/types/subtitle.d.ts": "d25b470e47d6a9bd696d9c1ad8adb58e56a208f05695186d513bc8c43c2e8acf", + "package/types/template.d.ts": "68aed9e97d006d6be4fabb8504ca84dafab770b0925f4d6e7319e67c82f21b0d", + "package/types/utils.d.ts": "494ec447ab467a07ddd7a2c2abf778b3fce69fd28a09aaa8ced9759f8de2e3f6" + } + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "archive": "artplayer-plugin-chapter.tgz", + "sha256": "178e7264d833ddb05f013772c8ac111b2acd46fa81284bd393b19215d3c772f9", + "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": [ + "DIST.cjs", + "DIST.cjs-legacy", + "DIST.esm", + "DIST.esm-default-only", + "DIST.esm-legacy", + "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", + "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" + ], + "types": [ + { + "compiler": "5.9.3", + "mode": "node10-commonjs", + "diagnostics": [] + }, + { + "compiler": "5.9.3", + "mode": "nodenext-cjs", + "diagnostics": [] + }, + { + "compiler": "5.9.3", + "mode": "bundler-esm", + "diagnostics": [] + }, + { + "compiler": "4.3.5", + "mode": "node10-commonjs", + "diagnostics": [] + }, + { + "compiler": "5.9.3", + "mode": "nodenext-esm", + "diagnostics": [] + } + ], + "i18n": { + "package/dist/i18n/ar.js": "5885c469efc9f07aafd6a4aa6698edae2c2683f42497ebbe15374130f9b6e2c7", + "package/dist/i18n/ar.mjs": "a275cf39ae2317ea1cea73b65ba5451a909b34a881d35920391cef2ff0d6a86f", + "package/dist/i18n/cs.js": "5adef10fadb219948eb5e58e204207ca0afdd2dd941a08d9455fd302ef2447cc", + "package/dist/i18n/cs.mjs": "2d274b61c2be9a472a3cc19dfa775e6209867f8d1d5a9116923f075446f47969", + "package/dist/i18n/es.js": "4c6662edce1398d0fe285978df83b271cce23e4f24e0e6a9d24a5b8a6845839b", + "package/dist/i18n/es.mjs": "09c0806a979feb4ae0e3ff32dbee9fd435847d3a66f80b6768ff69ab63289696", + "package/dist/i18n/fa.js": "db37cade9454df0b829c514e088d4d9175199faaff2b4a7838e6a401741131fe", + "package/dist/i18n/fa.mjs": "83290582155ee2a7a08a8c9cf8c2903545e78260e81a2a091092f3fbe61b4dd0", + "package/dist/i18n/fr.js": "54eee11fdf245e9882cb1f440f8909ccb8112f2e10722447cb313cab4752abea", + "package/dist/i18n/fr.mjs": "621844a04365da3d9e5d225d64e233d322cb9fd9c1ffcc2db77e5d7e0e78ea8e", + "package/dist/i18n/id.js": "5d4ee91a123c417b5b2e84890d85f416444389bdcd12c40d49073e1061796463", + "package/dist/i18n/id.mjs": "ffca08de9515704ef160dd902534df4b4113ff3f62b37f70330264d27daf5c34", + "package/dist/i18n/pl.js": "47e0d39623896436722439c758488ec660752c56a0294375bf0fce4f3b2aa27b", + "package/dist/i18n/pl.mjs": "05fbb3b2d09b44b5d3a237ea35a1f6865d45c2985e32b517dec4a00670cddebc", + "package/dist/i18n/ru.js": "3af3b15b1554579352b9b1ecfc8ac27abb584a5af9bcc7a8369a813c55df8834", + "package/dist/i18n/ru.mjs": "12281df03fc45c40ab8ad2a7dd8bbbab35f086dadd7e51f35e27826fff16e1ce", + "package/dist/i18n/tr.js": "0f8da88d4f770d9ec2e83311bbd6cc6ecfc0b2bbb3997f8db8eea8b795746967", + "package/dist/i18n/tr.mjs": "ea533927a7f32b3124177e87d9d5adbd279dc80efca7b11ad94696b3b47f7e94", + "package/dist/i18n/vi.js": "e3302f5c90f3e7df4bf8667c17598d0e46b66b31aab0d94fa70f3e617b5277c0", + "package/dist/i18n/vi.mjs": "f7a0ce8d821bff93354be31922a73be854a685e14170e8875cd5375f155e8737", + "package/dist/i18n/zh-tw.js": "13446c81dccf57e6b5d2be0a55b8ef6a668c6b8005ef4a497439557d6ccb16ec", + "package/dist/i18n/zh-tw.mjs": "730ae246aef8cffb34d7ba3b48aefab38fa812cf84ea7ebbd827f8639ee7eba7" + }, + "vendors": { + "sources": [ + { + "file": "refactor/baselines/core-vendor/screenfull-6.0.2.txt", + "url": "https://raw.githubusercontent.com/sindresorhus/screenfull/v6.0.2/index.js", + "sha256": "4246711b342018b0f257f8fa6047f240a21af6218c7e79cab5c662e810bb3e01" + }, + { + "file": "refactor/baselines/core-vendor/screenfull-license.txt", + "url": "https://raw.githubusercontent.com/sindresorhus/screenfull/v6.0.2/license", + "sha256": "5c932d88256b4ab958f64a856fa48e8bd1f55bc1d96b8149c65689e0c61789d3" + }, + { + "file": "refactor/baselines/core-vendor/hint-2.7.0.txt", + "url": "https://raw.githubusercontent.com/chinchang/hint.css/v2.7.0/hint.css", + "sha256": "a804fa4b607167e579b39d192f1a29d2b27226097094e0351f2d46ac8ebaa864" + }, + { + "file": "refactor/baselines/core-vendor/hint-license.txt", + "url": "https://raw.githubusercontent.com/chinchang/hint.css/v2.7.0/LICENSE", + "sha256": "55cee0a0645d18366eaa0cd21208c224568e14c38b7894e0f9ff537702ff8ea0" + } + ], + "local": { + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/style/hint.less": "e2dc4940e6b212d8da75a404fd5ff1ad894008457677bc37554c6b64b735bc31", + "packages/artplayer/THIRD_PARTY_NOTICES": "b77b5b46b79fa0cda850b0781f78c3b1112c4ed9672fa291956fe8eff53098e7" + } + }, + "browser": { + "stats": { + "startTime": "2026-09-11T03:06:19.514Z", + "duration": 243599.64500000002, + "expected": 1119, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "candidateMember": "artplayer.js", + "candidateSha256": "c768d111782b102062dff1eb75320bd99404efc59956445e7c95d598c90d0659", + "displayCases": 300, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "nativePip": { + "chromium": { + "capability": { + "enabled": true, + "request": true, + "exit": true + }, + "playback": { + "window": { + "width": 320, + "height": 180 + }, + "currentTime": 0.039317, + "events": [ + "video:loadedmetadata", + "ready", + "video:playing" + ] + } + }, + "firefox": { + "capability": { + "enabled": true, + "request": true, + "exit": true + }, + "playback": { + "window": { + "width": 320, + "height": 180 + }, + "currentTime": 0.167841, + "events": [ + "video:loadedmetadata", + "ready", + "video:playing" + ] + } + }, + "webkit": { + "capability": { + "enabled": false, + "request": false, + "exit": false + }, + "playback": null + } + }, + "cases": [ + { + "id": "aa892263c892083d7932-13db7df9f8d700edda79", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-af27eb5638cea6dfe907", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-14c8ec42e6b63b71f7af", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7b9949b48fb7cde7ed81", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2474cead0e45468fdf72", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-92f6a6d9a13ed0db69b7", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-c38f55e5356c80555777", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ce5a4349c94e7573f2df", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-745cf7ee3dc9fc8920ea", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7034aff5865b19493d48", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-3f7f11168066bc1135dd", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-98f452e8fc88900fbf7e", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-c075e9d7be551f55dc98", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2bedc05faa553d9d5e75", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2d30e8fbce3826e3c15d", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-0a87800d172dcd9435bd", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf7e525a2755f0c86bea", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-e4470972e51039dd2948", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-259434dce8ad5217c100", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7b3ff84e07f9b6519b6d", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-03a359bf96cac72eec10", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-3e3a0590e83bc657c777", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-a94d3e2e3468e36b53c4", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-a4513ef73bb7d291b1de", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-907cb350996072e49f76", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-1f07c4052b68dcd5fcb6", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-dfbf83aa28cd6f99e6fe", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf995dadc1257e9111fd", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf0c802aa1332ce3f50c", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-8828838dbabcde8784a4", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-d78fda3b4a4f188bca8f", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-4997157ab3e3b52575df", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-8dca6d7565c27e3cf00c", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-0dc7ef53e5e6c1c6a095", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-41d8436843ab4e0c4a53", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-22beee8392c7138d3eef", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-db259a3d649f557bdd8d", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-6ee40eab9446590238f7", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ac09580cff29b5c26244", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-191c4adbf7f0bfd11d22", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-1d69886cc1563158b162", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ccd2c30f32a17586ae47", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b64859461b5705d1cf09", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1cddd0b156a2290520d0", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a0ff31c497eb06cfdeb4", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-48a8c2fa6b32442681fc", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1ae60beaef7bc0cc1c93", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b405a3930560f4a322ad", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-23975233833f7314852d", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a2216a5ae190e64c0c28", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-fb9f50f4c4f1cf9a81f6", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-537c7bebe8e335d5ad67", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c9beea42f671df625472", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1ba81907a4dbfb985f88", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-72fc63307e889563b0c8", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-955901b7c9b5f75c7b1b", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-05c9a93bd36ae4d71ecb", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-75d44a2ac5d30638ab32", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8bea5b2d30fc513648e3", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-5e1987406b361d07632e", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-0444b7d85afc918256d7", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2f11ca271cc2f6668307", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b2817b31801e2c0549f4", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c0ae2825f95023de5382", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b0fd67600676be07f53a", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-646cffec899839d783a5", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a4bacc2b948ae9988139", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-5de7dc1781c68d66d249", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e2e82a24bc140d731d62", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7e771059bdaf24920387", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a67e3762e19c71f868db", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e199356f63d8d0e7e9a2", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-40af3bb8e336fdc2335a", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-621ba9de5d94c05b5cf7", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8317098f87d1859e2dd5", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1c8e447ad7f0fa9e8eaf", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-bfbc2bed73e613bd99c8", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d36a9d234b493b84426f", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-bd1fba69aa773e1f9339", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d3a7712862581da5e75c", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2107d278212d36d8da0d", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6b4fbf1d3182b04d96c1", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-04f3c73d8294ca07e6d6", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8ca066bc5b5eae539a24", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6d330fa833123b6b20ae", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4c8fd972f78dd9f2f4f5", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d48bb7baf38a31478a96", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-374314906befc5bd4abb", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2c8af0a3cc8135d1ecb9", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-ccba8bf8a8ae879bfe04", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-71c2187dfae3d083b25f", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-9cbfad2cb618fc3df484", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-479da8672c58208a8f64", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6d058a213fa9dc91b39f", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-de54752fbbd7c23b614f", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4f31edb98158d9461c54", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f28b63981b091141e37e", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-84ece502b0a7e2f6b7b3", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b4e97f806f7889922a7a", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2743285543496df7fe1b", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d6434aa47c57afe2cba2", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6dde4465bb116870696e", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f07afacdccdf8d37a3bf", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b9585d2981c5e97120e9", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e94b71940033ec64bfb2", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b501659d6692e6a3aef6", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-605545662d878960f7e0", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-62a855d83edae78c8e0c", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e5ad7ffd21eb01026e3c", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1cdbb2d211601ad9049b", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a1482fe33812e30491bd", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1b4a508565aad47f08a0", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-eed9dfd6f3a3915a8ab5", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7b1c657eabadad7a4e0b", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7e9a8def3dbc766cbe9d", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-226371bcad54f04cadac", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-593c07ca263ec7a933ff", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-664754e838f49dc96b98", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-195208b0571472607e96", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f85d899f5dfcccac78e5", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-92f3e716e64a7953a41d", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1aff62157f9fbb1f88fa", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4a9550c051b51fc07942", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-23bc5dfcd88b2bdfca32", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-14920589fd5937fe2097", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c22d9f44fdf7f96acb27", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-bce9960eb782bf3b388d", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-3d865d3ab8a953516b83", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-3971824465d64033c64a", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-784699458b9db440715d", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-e56018edc0c598cfe3a6", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-a0ff3ef97b2bbf67fef0", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-c38fd837350d34f82b4d", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-75441bab4ed44b490b3f", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-d07660cba382135f5e45", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-c8126a2ca83e05a31885", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-a4be546819cfd9b17a99", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-43b0ce05e60dabcf63cb", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-215c4e43e0c210b6c91e", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f51783956841921f653a", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-060b7fef9ab61ca8b51f", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e0701300b28eb93d84b2", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3ce10fb9e5feb9de0209", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4470a8c5dcdf58209d68", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f0b08a105464db873a3c", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-77370983ec73972d14d0", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-cd81168e76f3e6f8034e", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-4b38710a4241fb8efe81", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3f08ea1ba290c5e0de00", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-932ce5acf10f04835f38", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-6f12d4261b9f612c4afd", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3e31af20014f27ee9e5b", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-8a5dcabf07024f483997", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5ca7623e1e9824c6ccc6", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-6b3e80d3ab9d74293e49", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a469168f1d396f999be8", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a555e0648a8c5972e35b", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-71749fdef4307b96761d", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4edbd5dc212ac30a7bee", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-83c2f8a16d078a06d1ae", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3f48f4cc7fc5d5e9e98c", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f413428a3ac2b2788921", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-03f107aa3c92549e8cec", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-c63150bb39f74f89e359", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d1bedef93dbb2da29830", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-7ac118b7169027c52d4a", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e6d71f296f035bd569a0", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-641c8ca6813a23b668ea", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-1da7888e6f7a6eb19da5", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d25b39ad88db7e7b2bff", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-3d8d63a748da48094a7d", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5c17ee11f56d60e5daf8", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-979bc6ec3ee848383b3d", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a51cb8dd4bd7141ba7c3", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-b8361baced0cd1c4884b", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4a7f7248dd0e4bb4d117", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f1dbddcb8b6c55bf6abf", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-c28aa23669da794975fe", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d74f1148dcffcc4ba48c", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d2c53e913102a1af553f", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-96841fb451ce9297d393", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-7c96036f21956e3c646c", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-2ffb342b36c816963ff6", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-87a697176faffed75607", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-8ec24e59d1f42fe9d061", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d263205b93ce3716eed1", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-0f43609b9bcf28f089a3", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-5448bcd8bd74bca095fa", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e9ece5718b190162c6bd", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-03a8016bb2aaaf868aeb", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-2e1de5378e019cdbb636", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-b32fa9f007198c281028", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f515d4587be9d12105c4", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3afffa70279f302e77e8", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-1d8ce60246227b370e0e", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-71ebf721d07c19796847", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-672938aad25b617e5f32", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-0435322e0776c1c6db98", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-23ae836ca899325453cc", + "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 + }, + { + "id": "ea14eaab73c72643e734-5d87bb95ffd4bf65a4f3", + "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 + }, + { + "id": "ea14eaab73c72643e734-0e97734020dcc6df9f26", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-8bacf1c1c56de38bdcbf", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-51e147e0684036397c1e", + "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 + }, + { + "id": "ea14eaab73c72643e734-59dd6298bfbfea94c275", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-8c03ebd32e75e51f8e34", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-f4f0db9972fcc34e2ab8", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e09e6f9d356868edfd1e", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7968deae0894a7a41745", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-d2ce1a7a9b2ffa66c042", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-2d2e74a3704d6964ff64", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9f45e376ea3da4b17c32", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-44525e439ead5cf1926b", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-13923f8d94a0d0ae4937", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-b30f9705bca57697114f", + "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 + }, + { + "id": "ea14eaab73c72643e734-a7d18ff2f641f5cbf514", + "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 + }, + { + "id": "ea14eaab73c72643e734-e0a0990679eba59f084f", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-d07e0dccd2ae40c36625", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-588c0d140bf9efd60a8a", + "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 + }, + { + "id": "ea14eaab73c72643e734-7d51b759d72f50c2e069", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9aa04acd042f2f815772", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-83c5a739fd19c1ee758e", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1be5ce38e6088062d978", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-266740492e18fc860ae6", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-5201d0b8a57c2e862249", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-40e808dd1c844558cac5", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-691006a324af76b53d61", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-3a3389d22af8979f8eeb", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-c40ad10afeb67ea2e850", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-10149aeb19bf6697c9b7", + "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 + }, + { + "id": "ea14eaab73c72643e734-1c6ef5e75874838d7120", + "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 + }, + { + "id": "ea14eaab73c72643e734-7ebd0a99b0afcb231926", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-dc5e7d775e8ad4bec7f4", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e4d66d69d8df88578432", + "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 + }, + { + "id": "ea14eaab73c72643e734-9c425dfa5bfae0c980c2", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-17eda50816e6fbbbca7e", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-efabd841d061bb9e2536", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1f196ca428edacef09ee", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-4ae95e66ac42d7d03f9e", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-6c413f210385d70a7d80", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-86d59b7185aae72ca502", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9a9e65a49548f6b4d6a9", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-509e6f68a4e4efa344a5", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7f99bc001b5cb7f460ac", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-39784f83c5a20ae25922", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ae72eb701fecb9af3759", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-c51f1e6e8e3e150cf656", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-93d2a37ad53cbfa50f40", + "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 + }, + { + "id": "82e9aa99dafaec340dc9-e1fe2e4b9b734ba3d131", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-f72eb06a65f80253993d", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-7ce46c729250e79cb277", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-150ad3f2de69d36e8b82", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-130924bf85ce0603c3c2", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-76381e5bda48a5ade3a2", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-a0ff15ba8484c82eb5d4", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-1dd95d3d390501835602", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-4895669ba1966f650b48", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ad42062f96fd6eff1e57", + "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 + }, + { + "id": "82e9aa99dafaec340dc9-f3aed2b29f46acf70e9c", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-d4a7ab2fb9f82bf30b31", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-1aa42586b0131c02286a", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ad1af31ee3dfc38e3f6f", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e6fe305f0c0d3313abc7", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-cf1964446ac3f3a005d5", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-7bfca3da1efa390f1d78", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-3bb82b015b925c65648f", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-c0677c484632220c9e08", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-2d734612eafbf347a12a", + "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 + }, + { + "id": "82e9aa99dafaec340dc9-9317141fd45591056bf4", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-48e2f8d5a7ed9f6bb5a0", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e20a77918392d00be03d", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-de4bddf17cef4be77029", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-93ccbb4b069002b19fa2", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-0874de284439b96ad2c4", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3de9b990facdeff0476c", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-749a7d338b2101206765", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3e6382df01316fb281fa", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3bc55ca3eb9f410ec0e5", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-90f2213c5aab99e4e570", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-1dfa2ee5c94403260245", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-86b43820f5b552d786cc", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3dd543ca3a3090d34fbd", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-c8c02cdc6e6c0fc1420d", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-9a4914e43bb12fbeb582", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-769b87498109362f84fd", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3e4973914f06c39b6698", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-083974800f2e8879ae1b", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-641a2dccf8325c290c99", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-4ae457363eab61ca9ae6", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-8194bd99f36b6e951031", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-fb2e3177eb20d90269fc", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-2b7df84230e1938edd1d", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-ab2589367119fda8a5c2", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-50ff4f070fa19d28d259", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-e3c66306c7b25f4f4e08", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-aa481f1919609650e0a3", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-5f4c93857986beeeb8a1", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-bd3d36fb7c393b6fb340", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-711513ba84f86888eabb", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-218ffe39dd11365c7b9f", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-39b746d120824d46ea24", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-7faad1910240a59dd0d1", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-25a6bf8bad817690412d", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b29b1c45e6d1ec961272", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-667bbcd209351537a529", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-69c72083a6301a7b0a95", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-967a82e04705cb8ce7f1", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-4b3a751945fffd4f1a50", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-d7bd4e5eaff49ff3f6bc", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-0130a4a91c9404610c5d", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-6bb9d58f98fdcd85523e", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-38e55045d1be4acd5358", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-3b5e09ff69da4caa4ced", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-83bac7c7daa4e1fb0eee", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-0c5ae0e780b7c4cd4531", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b025eb13913d88dafadf", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-8afabec893b951bc9dca", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-1347f52c5334f122e18b", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-338fd2cfd69b416e5e22", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-9b82c9a55c0a272c73dd", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-e2033bcf8e8df5d25107", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-820a88dbf4c7c26b97b7", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-4bf4e63de030442894fd", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b3c6572e746e10e018ea", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-7b9ff7b1d7be3cd2c923", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-33f5644884ec9ba86bcc", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-2b06e449e9aee6d0450e", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-6941bd46497d1d2ed300", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-7fe227b73432db99c992", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-c0d916d83a69c0da121a", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-bafeb7f5931093c7a39a", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-cc32f7d91ce9e4df9fc0", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-0ebaecb2cd423a62fcf1", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-63d5f364fb9be03dfb3d", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-4e88cd81c30b7e5827c8", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-6e8ac8042e4aa05ddbb9", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-e86d33c92dc30d00cf21", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-b7a4cf05e951b7de5920", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-d8b9352760cb4971e37d", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-8fef1588177f24706032", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-e50eb3463d090abc7b88", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-ccb72602fd5954f2946b", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9b9158caa8753869e593", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-8a3807010e3dda6b493c", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-aa894c121cbb637c2356", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-1a2ebfdf05d5e3422606", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-dacf4da548671cffcf41", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-3fb0d0152310ce81c940", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-a2863c68ee28f3519445", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-9a88c32f828a7664851f", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-0d55461371288f7574df", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-daaefa1bb396ff5f0509", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-f092d45564e8b3510bda", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-643e209f256d1a250a16", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-7fb7121ab78997abbe47", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-b7e30679e943616dfef3", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-41b8387d30bd3355cdea", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9fbdd4ca5d22c59ccd22", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-208f9783e628fcb9f8f6", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-9b25a8ef63de7b4dc979", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-b6eaa1095fe80688f08c", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-217eac71a398847de922", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-13fb46b81b245d60cb62", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-2388222367857a3e66e2", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-13542a5bca0f6c66c1d4", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-55a303d76fff18e9c543", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-aa7ce7a489558e5015bd", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-a07eddfabd5626cd0a2a", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-be81b8fbab088b300863", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-219d49c53f695202afa4", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-7c345ddfdfbc22609add", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-a266ccd310d1805953af", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-a4537e5ee57ecc6df48e", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-8789c7a223602cf16bff", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-3083605efadc1ebb2817", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-d14a5ea50291afe6f9de", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-d8ab6eb3399b84992a2f", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-550cab25cd4472ab5404", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-815457e6e43f6215cf16", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fb5d2acca03e53a05fa9", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-938d058c513b2c6e4a7b", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cc2f4dbeb12688fc0d09", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-13a224af21b3d0914046", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-0139c3c03ae78094f003", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-56fcf9d4ecc6dd2b5317", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bb9a8e784bc0eed2746d", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-f8713bb4e572bbcdfa80", + "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 + }, + { + "id": "fe39740769f1a80c4f29-db015bbeedac5adcbd10", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-19ecc671e1e026bc0ded", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9ef90c68539232ed41a5", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-21cad0e9cdd6d2bfd1b1", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cecc49e625d4d5249b11", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bb05d7f99e674170cef7", + "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 + }, + { + "id": "fe39740769f1a80c4f29-9646aff44447cc995bf8", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bdce42f9d74c3175e0d4", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fdfa7d6a3e6cba0ab22d", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-7218f7cbdbf7c782e370", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cc08e8366aa5d34a9c29", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-80abc0538891ca5f3aa1", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6d04590538d38c42aad5", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-c57605f5ef7b09cc636e", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-0ba87022d3f706fdff30", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fe1595dc54e07363e691", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4297141ebb2129c56d83", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-63c383aab40510893259", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-8b1e8a0ed4dff57437e9", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9fdb2090b41f1f3ff3c6", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-23d2a65968478f02d44b", + "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 + }, + { + "id": "fe39740769f1a80c4f29-a20b1cb4c50409198ac8", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-07e5b86c2ea67d5bfe00", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-021c130be876d25ba481", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-842e4f5ea371dde0e5c2", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-137445c9986c9c51f2b2", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-da0df43eb60cf30984ca", + "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 + }, + { + "id": "fe39740769f1a80c4f29-2200c9b0e251b0d7c3df", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-80f4f73c29520d56a77a", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-24afcb40cac5af9d1385", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4e3c4d42cfd2be629006", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e9de1c8e6c2f74726a21", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-a7b2b5adde5a53dbe684", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-b70a7b7a9d964994eb6a", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-226a392ef76eb6584e8c", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-683943286d8f1c511779", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e87d954b29f0e537aafa", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6c492f1a4ee91737fb44", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-222bf68318bf2fa781e4", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4abcc05151f508b6b38a", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e62178933620bc510f18", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-936b9f3b6aa4eaa086bd", + "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 + }, + { + "id": "fe39740769f1a80c4f29-6af01df3c5e6334b2804", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-37632dea3a3b0bacf658", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6af0c468750891cc0795", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-7c85395365aabb2689de", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4096b3070bc74225ccef", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-45821ce9036c86d58429", + "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 + }, + { + "id": "fe39740769f1a80c4f29-2b3339054c6014e3d92c", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-1f11bfc1f0db92a746b3", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-5dcfac157f8728da6350", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4e69e56ade45d1c34c23", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-df9185e3b4b991a41e64", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-ed9673608bfce2021867", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-24b54879cbf233713158", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-88ac928201db18372b56", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-e6d95084fc692fda4982", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-c596a9468fae531af4fe", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-35933d1aa16aed20c273", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-284569d9920b0e711743", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-f133edb484cefef36fa5", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-b6865d33ac15fe202ee9", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-874d84ca789695182779", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-a4af7d5968980731d353", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-46ec1b4d191ce6ce2b87", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-c065a965bf03c20c92e9", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-5a43a2d9dd07eb718eac", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-5c900727f4df105d31e1", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-48f5ae6cdf42faf667b0", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-8ab1ef6cc7e44699a093", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-823f4e17aad9a4475863", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-7a655be064429dee0a96", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-acc7f1cafcbeef593883", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-4b319da242a0d8c88898", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-a2ac88d6cf9bcb87bc6b", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-26f0718fb72ab6480f46", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-9fe68a142a0bc1358130", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-808e795ad0ae6b29162a", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-7579b31713d2e73709f3", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-b22bfeda45eb2ca888e7", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-cbf8c58deb5fb97b5f71", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-49920d5cdcd992e18848", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-89197327fa985823badb", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-39a5048a03780f5926dd", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-38816d0b0af580ec7ae0", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-fb11c3a2d7114629dfc1", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-04ab8fdb013a043672b5", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-c674c60cca295235cf91", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-461f5dd6653ab5f2a639", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-27a5bff23ff7f1de8dd7", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-497b96f591affc76d55e", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-161d08b4110420b80ac5", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-c204080bd3b07a435032", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-9926a5b91c5984e3b054", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-6cc5ee1c72355fdb1396", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-60b0c86e91e11633d921", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-7720022e29c29701e505", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5cf5d68bdd537fd238e6", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-dc4dd75dcb489b80e3f7", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fde552e9529a19d3fecb", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-a7eecc22cacd33b910b2", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-965cae8eb7530de807fe", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-187c124ce8e69535b346", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-4aa95e812cf8a32b7adb", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-0b25f726ad05ae471db3", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-b943b423ff6eae4207d8", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1de19e97f5545df7afba", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-eeca99dfbfffba631604", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5bb9d55b4fcc0d96aa0c", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f08813139950541c5009", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fb6ded7b3f2a84801a6f", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-244a33407a1a4f812e79", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-532e0d74c736bd1a0a96", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f2e118615ee7bb5a6215", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1a9c3a775cd64374bbb4", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-362578108b38e76fbb38", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-13e3feb76468dac21311", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1bfbe29327bd8d169e61", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-aec7df62b58d89b641b9", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-3f5d5b7cfda98d08d6f3", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-38d36f45d72a4173bca7", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1874e2851c159cb95e46", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fd0415b8257f201f89f4", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-382b12a6bab3d4b449f1", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-bcf78818601a8279511c", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-6919f1e24909ceb2e9c2", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-032298add8fa5c9e6900", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-9eeb960c866cb8e40ae7", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-495621812ca11295f6c4", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-278ac9215c6ee4ef7a0e", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-281de4e437f228cfbf71", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-295d34734b65043ad9f1", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-eccf52e9ad978c3fb6f0", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-997c6976d105bb92e34b", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f8ac31a8f379e827afa6", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-2696dcfa7d78664906eb", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-c987918ce4081b93f4a5", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-ca7249b272a4ee995262", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-31189dc5c67888379803", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-2095690dc9b524b59f2e", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fd3da8b80bde24b740c6", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5bc8d77279a092208982", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-617565d43b891af783fe", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-f9616507688ef54da419", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-26f0e410fe8fbef993e4", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-82f480adbb99a326dbde", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-5125ea2213ff5db2e37e", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-826b6613db8e2561c1f9", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-a0fa0283e2778dc5de31", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-fa9c790ee5f9cddb03f6", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-50d0f3b11ab1c6d2a851", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-58c86f200056ced2c1fd", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-ef8e8b36cd6be9ade13c", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-412a59f5e374b192ab8f", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-7bea54a023db77650f45", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-f2a1eea4a9da71d32455", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-0ba262110508d87e2629", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-89a9d197048808466148", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-cabbe9eb64dd98cf1577", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-5f6824deb87c02f599b8", + "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 + }, + { + "id": "24da4743f3e5db9f15e2-ec4b2c508a72550ea58b", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-310aaace35717117379f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d69b68b0bdcc53067f53", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c1a588135d6cc568e6fa", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-97e1208644b9fa58b8b1", + "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 + }, + { + "id": "24da4743f3e5db9f15e2-09675477605b25710801", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9e893625c48fdfb954fa", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d6b81653bb60630a3599", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-66a15a5984ee4598f0fa", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d7563229ff93d6112f7a", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d51274ed9cc2dbcfb578", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2c737f670669e27522d3", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-8995ac2dfb98da407afb", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-01938547b760ce9813a9", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-03fd75c773964be30538", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-4e759bd25c03f8a5d10c", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-98f620bde5cb9a1b371c", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-0764e8c8458e141bc8f2", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-59ab8baf180ad899b67f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2bf2947fd3d500d7172c", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-87e5729cd74cd61fb7c3", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-46a350c4c851b9f21238", + "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 + }, + { + "id": "24da4743f3e5db9f15e2-4e8564bdb7bf0592a134", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-17ef0769f5ab192ba955", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-43c293f7c92733bcc08b", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e24f37c60c9773759771", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e502fb517997f1b53153", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-04fe566dc8e712f78ad3", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c1083b5c3aaa666a25b5", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-965d4a265b14ec72626b", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-aad49f66089770417b5c", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-afaa58fa5e14ad72db35", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c460f1702b1887cb0943", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-eb991a205aeec0eecc91", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-bcd222ce2c4830ef345e", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9183819e25f74564c41f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2c757941b4feb418e86a", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-342135d4e67724c3cf83", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-97ae305550aa393060bd", + "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 + }, + { + "id": "24da4743f3e5db9f15e2-7a2bffaadd6727862592", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-fa81266d048708984784", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9b9974717b4576aa1ae4", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-58b7be0d4b52aa9fccb4", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-fcb2ab222414744b8ea5", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e6130ef57b5ab5661f42", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-ebadf97bdc5e9f45affa", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9ee63e8b728f62bd983f", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-021200f38ed02bb50845", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-03c49c3e845e96f8e76b", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-1bf7e7b8230dff7a356f", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e1ffd301af299b9846be", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-d1cba7c810d80b340f02", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-b18e0bd87418016b019f", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-f640c192434bf9a64a7f", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-af04f2118c29852ac4d0", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6bbd26e23fb3429993b3", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-78efe4e7a850b2a90ebb", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-dd98a66249e18d35e4ec", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7e56c82040d8213b52fc", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7587ab0e8e449207ed24", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-5da1a688dbe2217facb7", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-489c3bd67ceac85c7d79", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-4d1c0bbb0d31efac6702", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-83a5f6f72a73e749b6fd", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-c60ed5afa38f7991685c", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-1961de75defdc952a8f3", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-351ed5a2908f4cc9619c", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7954fe1c578a54eebf8c", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-36154f67953190d1bfba", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6522dbb08c1b075a5ec0", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-76e298b978895f180911", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-77285e408518bdd6dee8", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-c8f1d687675a279a00cb", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-3d38bfd5b7b08646ebfe", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-70526633595037330da8", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-e00d282a9b13f205b9a9", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-ca150c7e341afc79085b", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-de68c38b7c4aa90447d4", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-4bf9b7e006db011964e1", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-b81bcd76f642b8cd1cb6", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6a1c655a7541e2c283c5", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-33ab58a217e5ed46af64", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-6c3e26795bad7ad08640", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-081e4a3c2efab5a6a4f8", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-48f3dc84a4b45ece0f66", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-bd8e568d3c301593236b", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-a20205da01df1b6d1275", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-cd03a72feb502b43128a", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-c084c9d9f3321e48be59", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-291a97e5971de8da34fa", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-96ad9b36215f1db666df", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-0ff5f41421512bce0682", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-85d3c1a084877cb32e68", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-9a764add8106b570a9fb", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-4f6c3e8455782e5592a1", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-321e89c016aaf0a04e89", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-3835036f94dea4e826e2", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-cda798777baabd4bf688", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-685f7f019e46ba558b9a", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-640ede7d3ff202fea200", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-254917f54cf2302cd6ae", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-36849c7e4b2167768c04", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-ac5d5c862592ff76b6c7", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c3ffd08e95c46586ed24", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-46ca3a1867d4e79ccf78", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-330b06a4b4886d69f8a2", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-7ea574653c71793cdc59", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-494fdf7a643287f6e9f6", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-a20b9efe52074aba9a9e", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-f720c3dec109e51e7e33", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c7e1c0f20ca436a64e31", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c10d09a36296547cce19", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-65b87ddd974d9095cd99", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-f923d3845a11b464c735", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-71e88fe06828c0aaaa52", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-0e43bca78fe1615e1188", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-74b76fae26483153575e", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-f81f74c17d54e135812b", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-cb7cf3d37546dfaaa25e", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-ad243930eba7bbfca9ec", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-4f06979d10a0cc73f0e4", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-73b72e27dc0e279e1dfc", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-a391ecf6be83e360d5af", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-9886e61b50b0325f00b6", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-7661cdbadada621ddbdb", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-534b6a21f22d52437946", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-964c3e167f81d6c4b540", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-b8af7f6e76d64a404611", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-26e289678f8318df9985", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-a31d40ad896888983990", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-41f669bbff76dba08542", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-94ccef7d1b2712b3a8c7", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-0acfeccae2fa10a364bb", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-804bbc5c45a32217b23a", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-e1687b8c29a364456ced", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-9de93a65641998f55bfb", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-ae29a326f7d6b9244c7a", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-5642c616032ffdffac35", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-75b1d9674a6663bf2d6e", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-1e45a2a5dde8e9ffc1f1", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-fea8a7011bdffae81cb6", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-4d2842dff07972329923", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-5235450a56f738efeecd", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-6d06c3705c2addbb8090", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-1707b8b14a6deb4b2b1d", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-c052ddece9958e0555fb", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-1723a11b47d130206b98", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-b93e8a95aa929ea2ae0c", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-60bb8e6ab68260d8c6fd", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-55abe99fef6857550456", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-78fe676015d6e8dbc0d0", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-a24e837c0a70d9648453", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-802ef8362a0f403ae08d", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-70abbec3c9dd6b888e1c", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-c0ab35af2770dd5f4806", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-e72fde2e2a57668fa47c", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-a4df961c9062ebada00d", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-73e6bcb78301864d09a0", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-0f38da640b1ce0c5e360", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-08a820c1f1e532774cc1", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-0a6080d5d9c551bbbfef", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-d47adcf0c29980498c19", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-c1239d4ad067319ee2a3", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-229449f9f5a2f8fa7963", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-52e7670a5b3a053c6e55", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-7ddc0ea00c170012b4d6", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-dbf437be2f34861c5a0e", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-3c389ca847ff1e4c75bc", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-6542b91dece2a74614df", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-51b208ac054e2eb00b26", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-4f6db3993845b9ba2985", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-bf0574101b74e333abfc", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-b8e3d4f14c5274942e99", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-aa029ef04ccaa364abaf", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-884e7e97cc7f4601b9b1", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-89a5f36c70aeb1aeb725", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-6e80e6040b5d820ea851", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-89b1e6f236f0b07b34e9", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-76c423a2c23281a89f4f", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-f1b89a3a449ec92c4a02", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-846a43d5c11f461bc706", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-6fc43c2ad3b16ac57feb", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-923d4b452977986e35eb", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-3751522702f6c4040d89", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-7c1ede28fdbca2fdb036", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-2e71806ec46cfa3c8830", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-308b7034593f3aface7c", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-824de270447cd0289399", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-2e405967fd041e7bd63c", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-73ef3504117f77184a3f", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-273a8c96e455bc2cb3a5", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-421ad6f29b1e4edba558", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-9848ba9b5bdc87b7080d", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-fd0af30740777b8fa6f6", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-caf25f6ee3ed380b66a5", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-1694c548d47a5dfd7321", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-4a613122854d4efeab25", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-ce9ca8b3a37a93a751e0", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-a86fc2f76d5a0e73dc92", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-ed069932d1cecddc62ca", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-9a9f8fea7676c3fb1f03", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-7bb2424006b234f72e6a", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-f7838ff686e269e64cbc", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-22b53afce3b44c0e3b56", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-7de925a1d5f347027a30", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-d4bffb27232bd134e0ba", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-115453f0cb1f2df25c13", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-576425b00e3b37a5f55e", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-6ddec59a6b7a73444874", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-c4a665637742c22fe6db", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-05c7aa4a035cd53f615b", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-ff797d35cf4226a8908c", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-b321c5b060f24c0dcf7c", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-86838248a63b8cb598e4", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-f74d56109a0a98dbcf37", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-f2cd78f5c336b7b5a29b", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-687bbd5c29aeaa2087ee", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-8e37462e4a700a9d032d", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-8b838317977126c72896", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-c162cdb14c052116404d", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-0b01ed5f487c653ef5e6", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-3faf3b0b78cb6e5a7916", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-3cc483840fcb60da6de7", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-886e669450b0aa293cc8", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-5d9e035f106d302fa65a", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-850f54c586f39ff9ed15", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-b9482406e41527269426", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-472f4ce1e106982a41f2", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-e4b709b61462b8d189d1", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-9d3f428ef8c764b1ff11", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-6fb2012cd72d02b2a069", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-17106154f47c826afcb7", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-49817d29e2e8721cf6b9", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-0aa0a59420e90b9113f5", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-cf318af31bbcbc8c0d29", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-7172a28011c10712e8f9", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-db2b94c7c74a6265c7e6", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-ed084452ce2ddeee614c", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-deb5a4dc1d9142fb059c", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-bd60bf10694d5c9d5bc8", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-9bc90e10e6b91381b1dc", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-14c472cf2848797472e8", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-d3fa95cf4dedc7407cd9", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-fa5dfd957b26f3982f9b", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-84eecbfcd48fd0b44da4", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-7c987ef852f16f3323dc", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-b1e49c1b67e35ce90df3", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-a42dee36a9b3d9c4fa0c", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-bb6dd2a13ef876f27f20", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-f4bc95d33fa3669f089e", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-821001884db4778713ae", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-180bf4aaa10c590bd599", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-e6a6a636533e1ae93dfd", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-c80ec0bb00165ef911a5", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-1ca51d9b23c4840440c6", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-7529bbc5da7ba02e9881", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-249074f810c94193958f", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-5d6d4df808eaf0e9b59d", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-2fea8a03da06a8d155fc", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-84eebdf7a1b26709a4af", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-c6f3f4dbe1114df7bca4", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3b6abffecd638d7e143f", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-435c729ed77736ac49bf", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-b1d56ff1e9d1586f27b1", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-f48f91aa1d16a05778d3", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-2f0d8d05fb5628452b73", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3237a1637bb73b6d11bd", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-87851356a1e1b9a04832", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-7a52d540da49d844c3dd", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-2d1be2095bee8967662e", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-9e91549ca39177fdc341", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-9c6b842be6a0229603b2", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-da73608d2f06c5869eb0", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-04000d17fec631057431", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-eafb41732c2d02fa92d6", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-f1387f78049e2f96216d", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-04bbff86779db8d424a5", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3cc599e6ea966ac42f1b", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-6c81f2fe32d5bf59df14", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-01382f9e44ebfe71cd1b", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-7d7a52a1212aaa3903f9", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-e0bc3bdb9684a0cd782f", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-135d698a416df763c37a", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-5d1ce52c24eb280eaa53", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-cde9321fcd4606c1b6fd", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-3b4d510589021541d752", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-cf920f57a2f13b3ad575", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-57486584167b26522115", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-00fb29fdb678665bd82a", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f41eb20d274264176967", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5ffb3fde2da7d4420c6c", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-bf7338a3096200f9f48b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5d99a0f5b38ea58db833", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-15130b33d5a769fe6a32", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f4a165db0eeee2fbb2fb", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-1e6f34f81abd19db2f8d", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-f5e430ce64b390617ee3", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-dadb0014a2da497a555c", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-e14fb1f8f441e37f3b6a", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f5fb5476b00f686e7097", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-6ef2f1516fd5d9e51fc1", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-1142eddf3eb99d81c770", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-6f65c65f97d09691ecf3", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-b2bb869e9bfc30126140", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f7de42ba4922f372e409", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8b0033bf3124c2381b88", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-ee91e94bc145ebbc752c", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-0a784e55b980e4a768ea", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-53895d4a405ab4764718", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5a3db1f978360503899f", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-ad82945116d93adc0ee9", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-34b194f9407279f8831a", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-9dc273025bda0344f5c4", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1ada9c348b31da0129ce", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-fa685e4dcb072c9ea0ee", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-884c6de7c5b0cd3f6143", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-8c085c86b98980387cca", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-1d032d41a8812068669c", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-88075bd9b821bc49ad85", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-e60dc36054298fb611da", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-a97693c8c3afea09a84e", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-878e0cb15d6a04d11f7b", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-7d1e13e2a9ee5204d11b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-7c59dad85dabf535d30b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8310d1a5474799c482fd", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-22b4165ec09c3e56b7e0", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-91e7fe297e8a037196c1", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-3d9bb69b9a2c4e7a5f37", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-047950c0a6d89c18dc10", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-9682b6f0bf28f0a6701e", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-4c2944013559cfa3aa5e", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-2f87e96dc17cd24bf360", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-00da5bc0a7813116c372", + "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 + }, + { + "id": "6e198c9007101abd57b5-d666f9cbd2bc867bad9f", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-dd5a610bd634cf860947", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-17ad59cd7db68e82d4e2", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-745d515c00e5ef36e018", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-cf379c3ac3906fdbd530", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-b7c2d17089053cba66fb", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-903dd2547aeab4333b8b", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-dd7bc21d13c67bacec65", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0cda73e045d032d47ee8", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-2b2f887e4b2b9c1be8f0", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-c5b5c2f93a4e9a66cf63", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-357f232d33a60db07e3c", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-7785bf4b3b17c1ff68a0", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3b960308df208119cf5f", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-a39e2d52b8853c5c18d0", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-65fd62ceac4a2b0de679", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f0a0ba282ce64661d749", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-544d30d9ac046c59b7d8", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-019ac6cec34bd5492707", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8f9ac72827bec9ca6d46", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f9edbb240e681f54990d", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-925ded2c1bd757ab65e0", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-494124c7cb25ce9c8484", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-08ff1fea641c1071ce3e", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-5fc0cb0bafacd337621d", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-bda80a9e217d5482e64f", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-42a6aad1e0fdb0089e55", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1d6fe57647819834649e", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-76c4d4bf464d081a3736", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0f1cce7dc1de17a45a59", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-db50125db4f2a490fdbe", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-bc0f9dca801bd308ea8f", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-67f07edf6c0a08c6b68d", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-14422e8869a16392d3c8", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-58025407c8f1521df7d4", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-74c1f1904ce6d8baadb1", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-2ec13de1e4838fba9146", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6a86cf5a20b7f1eeb2fa", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-eae7ba2c99c1bda33c80", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-7525b67820217feb9c11", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-681bae4b93740ef5f0c5", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-90603a7bbeaac3ebac92", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1c9713c42a024b95bd44", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-13bd01f6910054eb3295", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-88dfa403dc0f8ba0f199", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-93362782d6cd1c9b38e5", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-151d89deff8c82884589", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-af17e6f132f3601b9340", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-fd13688753dec32d87cf", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-08bb1d125afe61dbdd5f", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6718d686298503531939", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0443b81b66ee434750e0", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-67266454faaf86e9f82e", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-30daf2d7d1aa4885ac63", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4939a26ab7be1b67bcf0", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f95651ee1387c941a464", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-54aa82fad20e6cdd81d7", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-88ef3f5c7107b92df586", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f5a885749ae7733db165", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-18a5161d5a026f9fba04", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-98ca74f8f55d4b15d8a1", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-50cee2adb9a3c61f0dc6", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6bff7e83b5206fa9d91d", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8173f024a9d58630ef0a", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-da9ef20e377375a16f83", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-07b831b27287c07fcc40", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-691d00f15d0081cb59f7", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-845ac433ce41eb556d00", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0a674a144ccfb1d95b83", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-e565aafcc819b2450df7", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-29089ac1a04857021285", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8ee8efd4c48b9758c274", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6acbb8df373136b70a54", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-07b30dc9529bcc05872a", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1d4a2e7780e6d0550948", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3db8330bddd94096be58", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-38ee4ebbf8170b376a1a", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-51b82f8cec6133b560b9", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4d2164eb08268dd10fa6", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-9bf6091babe12c0829ab", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-714d3a7f292b207efea6", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3aea2df8043c6a6e28a9", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-79d4c0f92c8e7ce5074b", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-e83b0e3f4aa0610fd15f", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4d1ddd2034d35cc4620e", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-524159ddf174094337a1", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-ba7af307dca325c42461", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-833e9ff88cc7391a59b8", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-6782edd72d6da4a4ad8d", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f252bd2fc447577759b0", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-3cfca19d21391eac95e4", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f888935069d847b893e1", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-6e57082f8837ec98eb4a", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-d249488159d1321fd2bb", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-df992af2e935cf8992c4", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-80521267c3361388a69c", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-32b0ab4acd28e0f0c843", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-2a9cd3695fb54d9983eb", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-e7b06471c09b919d19a9", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f9ef3279fa413557bf74", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-4493fdd9f9a0b065a5d9", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-ff9db48194323087ff35", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-b3f7622fc945984018c1", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-9007396b1c807988496b", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-7720ba65254587e4220f", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-0dfab8dfb052a78725c9", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-2206320b5471e792b324", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-42d36054a79412ea814c", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8a5fef92ae9112a22e17", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-7c15928bbf9cf5446364", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-3e105514fdcdf2109560", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b17f3a99113bcd921376", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-5a386ba920946118f5b9", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-f152343084d96e444c25", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-19e34f584147a850810d", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e6b47b2e4f1d89fdc1fd", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c54ff96a656f8f7e0614", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-209d6e601169222401ec", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-0224c5f81d88e9a76abd", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bbf01adc9fea833a654f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-df809aca00e2b669dace", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-016cc1640e3b3d043bee", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-07dc4321a38968280cbb", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-7334ec778cda78e83768", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-4a0c98327b25b0f53349", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-3d4383aae663249070b4", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ac1f881dcd7c9ea6b614", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2fc6f4437794b5fcae1a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-affdcf01df5b548e74c3", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e69a2633d1da5da0a033", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-eed34e3a1de997f80105", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-6f3db740e84bd4583de0", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-75a2ce3c50f0326338d6", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-40d428be335e78a03d78", + "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 + }, + { + "id": "bd8b578824fda6d824e5-1e51854f9804aaa89760", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-f0bedbeadb96666727d5", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ef9c82e81e4bc84eb35a", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-a206e4dec77195448b2e", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b6a8e78c8bade555f99f", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1da818cd320f200493dc", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-37e8784fe2be118a89cb", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-baf78a292febd2d0253b", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2f67378d9be913549ee4", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ce42453036328047efb1", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8354c7d516c210cb683f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c2c4c0e141302c3cef1f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-03df75134609c4dfbf10", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-23e94238a1be63a9aedb", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-306ec942a307ac4b332a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-27ea66e30846c6c35d1f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1ff068f72f09e1062c71", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-49268197eca684b03b23", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-45d66a58f8ace121aa3e", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d55737ce84e01c268c81", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-de5ebfc899aee6d78694", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-80a4fc6eab4db076a7ce", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d11efb83fe4bb3c07013", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8b874818fa453c7e6f49", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-644e384fedb167647bc1", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-97913b921f13e91b4542", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-315d8c53bcd83acda5c2", + "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 + }, + { + "id": "bd8b578824fda6d824e5-d511fccbe7e54abf3fce", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bf9ed48af22e7dec6f9d", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d8cac70b11a66ba978c8", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e0d22129fdcac1480ab5", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-75861334d0fffb96d413", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-4d9c22a343ef35f5b877", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ae3ab743fb1aecf74832", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e402f7c34fc93b9cb6be", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-946b1205dfcbfb6f7daf", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bd0e7d1620bf7e83e671", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-54c89f9444bb550d9372", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e0913a2d6fc2540d8a18", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-03dbb2c377fe45aa14c0", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-066d3480dcdc71e8a4e9", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-18cf581403b35016dd5b", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c7b04385144f290eee56", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-18e90e6d63836e36b04f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-350e2e7d4721dc11ee0a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8ebec3e26df820a018bc", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-da28a74d360e5e5f4da8", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b87e2eed66add761c939", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1eb214dd7fb6d08cd588", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-a9c047aa7f9899ee2e91", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ed84cf26fe663abba84e", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b975a9d80a73ee2c5318", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2325734fcbe9f19ef38f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-53fa73e3d56972e17fb4", + "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 + }, + { + "id": "bd8b578824fda6d824e5-68d9c42770fb755ff944", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-bf645b1a65cbfaea5769", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-9d765289d32be33b1358", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-aa26d2ab16bfa364ede5", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0e05941de94496050665", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-07b5247e88feb728a1ea", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-c585b499b392d1f3125b", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-807c73d105e8d88f3691", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-3a8724253f4ed9d64051", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0c1741b96b329426a59c", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-842c1a319c8ec887e2da", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0e3cc6ce8bb29447e4aa", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3157016a1f4a564e4e36", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0bf30ca101daa48f2926", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-f15c420a1fe6dde01ad5", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-d062fb6e304335da8017", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-ab3a301f236c4211d0b0", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-db1474abf9d021d54190", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3fad5bde9035571dfeb1", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-527a6a05cfabdad5e934", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-06d2174f2fcf7425f220", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-84b620f68a13175455c6", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-65451ddd2f6fb97e5b62", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-91327ada1dd05e2a6298", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-ea62643a3c6b46fbb710", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-122f023f6398972e230c", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": true + } + }, + { + "id": "ea1be0d464ef792edb71-651f98b0f143502c508d", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-65bebbe49c153c2d5f16", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-51c0c54a3382808aa510", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3670c81ddbb8cd20a30b", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-9d3c02ac24a72b007bac", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-62ac1fcd49c58719b731", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": true + } + }, + { + "id": "ea1be0d464ef792edb71-a0a212ed633e0fcae542", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-fdf8e58e63293f008154", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-6749a7d57a0a08031b98", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-c71eda7665d7fe280226", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0f9982e28da4776b41df", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-47bf44da43f7ea630c57", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-94a91f70513a4f3a0536", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8bed1f155fdd13a8d676", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-76ae798ce585defae260", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-940ea42ed81a2e76857e", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-fe6258362fcc32df0641", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-3976dbe5125baf9596ea", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-e85621f95b6a8e48ca8c", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8aa46f4bdea9ab2db828", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8da0c6598ba3b3f02663", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-d7bcbbb91d28521d7e10", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-737ee111c8455e9547dd", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-0a0f67812bab08126d1c", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-dbbe30e49f81e686c544", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-81ecbd7fd933b26d5381", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "webkit", + "status": "passed", + "retry": 0 + } + ], + "reportSha256": "a2d25653bee0dcbfb17a7a4191cb9041949a28acbf711a6c22ceaa5459736ce7", + "supplemental": { + "stats": { + "startTime": "2026-09-11T03:19:11.439Z", + "duration": 9852.841, + "expected": 24, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "candidateMember": "artplayer.js", + "candidateSha256": "c768d111782b102062dff1eb75320bd99404efc59956445e7c95d598c90d0659", + "displayCases": 0, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "nativePip": {}, + "cases": [ + { + "id": "dbbac41dc03fc4f485ce-1ed76b5f6a82de9d068b", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-3cefbcbec7deeff53d05", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-69355e4dc46467b0a9eb", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d94e9fc7c4dba97cc53f", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-61c4eabc80173b1e442a", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-71d443a2b6af5518b178", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-59cb2417e70f961c50e2", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-9c1d85713fc8613fc6fd", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-7c6a370020654bfcada6", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-30aba1a1bb1b8501b0db", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-15709a7d6ee1e1e37d05", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-1b85f275ededd6b4ce29", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d7c211503e05f9db4594", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-f8c63f06543266f0373c", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-55df032d48093a9a7a98", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-43883bd2151838bff08a", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-96cfaa6a8f4b9da28c64", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d322bdc5916e8bb4e882", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-5b6a7c315b0b983e8044", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d5dc97a19584f2c0bd7c", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-509d99c428ef04fb2e49", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-fac2aa15d600bc1bf552", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-5b23a746569631c03db4", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-bbd046deabc0ca1172f6", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "webkit", + "status": "passed", + "retry": 0 + } + ], + "reportSha256": "b7e823d0ada2ef22a8c4ce6bc1e79aa2fa039772511ba07f7d0f93f7cc42ff0f" + }, + "combinedCaseCount": 1143, + "combinedInputCases": 243, + "coverageNote": "1119 full-suite cases plus 24 supplemental closeout cases against the exact same installed artifacts; source and existing test files were unchanged.", + "inputCases": 219 + }, + "legacyBrowser": { + "stats": { + "startTime": "2026-09-11T03:11:18.260Z", + "duration": 246836.118, + "expected": 1119, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "candidateMember": "artplayer.legacy.js", + "candidateSha256": "11144499ad0c37ee1b2719992d9e9836b7d5b5abd7b37f6aa4928aaba05cc924", + "displayCases": 300, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "nativePip": { + "chromium": { + "capability": { + "enabled": true, + "request": true, + "exit": true + }, + "playback": { + "window": { + "width": 320, + "height": 180 + }, + "currentTime": 0.030881, + "events": [ + "video:loadedmetadata", + "ready", + "video:playing" + ] + } + }, + "firefox": { + "capability": { + "enabled": true, + "request": true, + "exit": true + }, + "playback": { + "window": { + "width": 320, + "height": 180 + }, + "currentTime": 0.144806, + "events": [ + "video:loadedmetadata", + "ready", + "video:playing" + ] + } + }, + "webkit": { + "capability": { + "enabled": false, + "request": false, + "exit": false + }, + "playback": null + } + }, + "cases": [ + { + "id": "aa892263c892083d7932-13db7df9f8d700edda79", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-af27eb5638cea6dfe907", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-14c8ec42e6b63b71f7af", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7b9949b48fb7cde7ed81", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2474cead0e45468fdf72", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-92f6a6d9a13ed0db69b7", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-c38f55e5356c80555777", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ce5a4349c94e7573f2df", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-745cf7ee3dc9fc8920ea", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7034aff5865b19493d48", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-3f7f11168066bc1135dd", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-98f452e8fc88900fbf7e", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-c075e9d7be551f55dc98", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2bedc05faa553d9d5e75", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2d30e8fbce3826e3c15d", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-0a87800d172dcd9435bd", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf7e525a2755f0c86bea", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-e4470972e51039dd2948", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-259434dce8ad5217c100", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7b3ff84e07f9b6519b6d", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-03a359bf96cac72eec10", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-3e3a0590e83bc657c777", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-a94d3e2e3468e36b53c4", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-a4513ef73bb7d291b1de", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-907cb350996072e49f76", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-1f07c4052b68dcd5fcb6", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-dfbf83aa28cd6f99e6fe", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf995dadc1257e9111fd", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf0c802aa1332ce3f50c", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-8828838dbabcde8784a4", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-d78fda3b4a4f188bca8f", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-4997157ab3e3b52575df", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-8dca6d7565c27e3cf00c", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-0dc7ef53e5e6c1c6a095", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-41d8436843ab4e0c4a53", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-22beee8392c7138d3eef", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-db259a3d649f557bdd8d", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-6ee40eab9446590238f7", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ac09580cff29b5c26244", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-191c4adbf7f0bfd11d22", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-1d69886cc1563158b162", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ccd2c30f32a17586ae47", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b64859461b5705d1cf09", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1cddd0b156a2290520d0", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a0ff31c497eb06cfdeb4", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-48a8c2fa6b32442681fc", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1ae60beaef7bc0cc1c93", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b405a3930560f4a322ad", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-23975233833f7314852d", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a2216a5ae190e64c0c28", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-fb9f50f4c4f1cf9a81f6", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-537c7bebe8e335d5ad67", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c9beea42f671df625472", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1ba81907a4dbfb985f88", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-72fc63307e889563b0c8", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-955901b7c9b5f75c7b1b", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-05c9a93bd36ae4d71ecb", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-75d44a2ac5d30638ab32", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8bea5b2d30fc513648e3", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-5e1987406b361d07632e", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-0444b7d85afc918256d7", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2f11ca271cc2f6668307", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b2817b31801e2c0549f4", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c0ae2825f95023de5382", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b0fd67600676be07f53a", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-646cffec899839d783a5", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a4bacc2b948ae9988139", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-5de7dc1781c68d66d249", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e2e82a24bc140d731d62", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7e771059bdaf24920387", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a67e3762e19c71f868db", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e199356f63d8d0e7e9a2", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-40af3bb8e336fdc2335a", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-621ba9de5d94c05b5cf7", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8317098f87d1859e2dd5", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1c8e447ad7f0fa9e8eaf", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-bfbc2bed73e613bd99c8", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d36a9d234b493b84426f", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-bd1fba69aa773e1f9339", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d3a7712862581da5e75c", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2107d278212d36d8da0d", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6b4fbf1d3182b04d96c1", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-04f3c73d8294ca07e6d6", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8ca066bc5b5eae539a24", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6d330fa833123b6b20ae", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4c8fd972f78dd9f2f4f5", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d48bb7baf38a31478a96", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-374314906befc5bd4abb", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2c8af0a3cc8135d1ecb9", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-ccba8bf8a8ae879bfe04", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-71c2187dfae3d083b25f", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-9cbfad2cb618fc3df484", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-479da8672c58208a8f64", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6d058a213fa9dc91b39f", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-de54752fbbd7c23b614f", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4f31edb98158d9461c54", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f28b63981b091141e37e", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-84ece502b0a7e2f6b7b3", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b4e97f806f7889922a7a", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2743285543496df7fe1b", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d6434aa47c57afe2cba2", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6dde4465bb116870696e", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f07afacdccdf8d37a3bf", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b9585d2981c5e97120e9", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e94b71940033ec64bfb2", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b501659d6692e6a3aef6", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-605545662d878960f7e0", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-62a855d83edae78c8e0c", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e5ad7ffd21eb01026e3c", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1cdbb2d211601ad9049b", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a1482fe33812e30491bd", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1b4a508565aad47f08a0", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-eed9dfd6f3a3915a8ab5", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7b1c657eabadad7a4e0b", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7e9a8def3dbc766cbe9d", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-226371bcad54f04cadac", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-593c07ca263ec7a933ff", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-664754e838f49dc96b98", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-195208b0571472607e96", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f85d899f5dfcccac78e5", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-92f3e716e64a7953a41d", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1aff62157f9fbb1f88fa", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4a9550c051b51fc07942", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-23bc5dfcd88b2bdfca32", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-14920589fd5937fe2097", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c22d9f44fdf7f96acb27", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-bce9960eb782bf3b388d", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-3d865d3ab8a953516b83", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-3971824465d64033c64a", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-784699458b9db440715d", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-e56018edc0c598cfe3a6", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-a0ff3ef97b2bbf67fef0", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-c38fd837350d34f82b4d", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-75441bab4ed44b490b3f", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-d07660cba382135f5e45", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-c8126a2ca83e05a31885", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-a4be546819cfd9b17a99", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-43b0ce05e60dabcf63cb", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-215c4e43e0c210b6c91e", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f51783956841921f653a", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-060b7fef9ab61ca8b51f", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e0701300b28eb93d84b2", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3ce10fb9e5feb9de0209", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4470a8c5dcdf58209d68", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f0b08a105464db873a3c", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-77370983ec73972d14d0", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-cd81168e76f3e6f8034e", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-4b38710a4241fb8efe81", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3f08ea1ba290c5e0de00", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-932ce5acf10f04835f38", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-6f12d4261b9f612c4afd", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3e31af20014f27ee9e5b", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-8a5dcabf07024f483997", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5ca7623e1e9824c6ccc6", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-6b3e80d3ab9d74293e49", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a469168f1d396f999be8", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a555e0648a8c5972e35b", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-71749fdef4307b96761d", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4edbd5dc212ac30a7bee", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-83c2f8a16d078a06d1ae", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3f48f4cc7fc5d5e9e98c", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f413428a3ac2b2788921", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-03f107aa3c92549e8cec", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-c63150bb39f74f89e359", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d1bedef93dbb2da29830", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-7ac118b7169027c52d4a", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e6d71f296f035bd569a0", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-641c8ca6813a23b668ea", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-1da7888e6f7a6eb19da5", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d25b39ad88db7e7b2bff", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-3d8d63a748da48094a7d", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5c17ee11f56d60e5daf8", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-979bc6ec3ee848383b3d", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a51cb8dd4bd7141ba7c3", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-b8361baced0cd1c4884b", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4a7f7248dd0e4bb4d117", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f1dbddcb8b6c55bf6abf", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-c28aa23669da794975fe", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d74f1148dcffcc4ba48c", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d2c53e913102a1af553f", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-96841fb451ce9297d393", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-7c96036f21956e3c646c", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-2ffb342b36c816963ff6", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-87a697176faffed75607", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-8ec24e59d1f42fe9d061", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d263205b93ce3716eed1", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-0f43609b9bcf28f089a3", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-5448bcd8bd74bca095fa", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e9ece5718b190162c6bd", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-03a8016bb2aaaf868aeb", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-2e1de5378e019cdbb636", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-b32fa9f007198c281028", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f515d4587be9d12105c4", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3afffa70279f302e77e8", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-1d8ce60246227b370e0e", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-71ebf721d07c19796847", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-672938aad25b617e5f32", + "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 + }, + { + "id": "7fe83a2e91ec089f5974-0435322e0776c1c6db98", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-23ae836ca899325453cc", + "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 + }, + { + "id": "ea14eaab73c72643e734-5d87bb95ffd4bf65a4f3", + "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 + }, + { + "id": "ea14eaab73c72643e734-0e97734020dcc6df9f26", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-8bacf1c1c56de38bdcbf", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-51e147e0684036397c1e", + "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 + }, + { + "id": "ea14eaab73c72643e734-59dd6298bfbfea94c275", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-8c03ebd32e75e51f8e34", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-f4f0db9972fcc34e2ab8", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e09e6f9d356868edfd1e", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7968deae0894a7a41745", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-d2ce1a7a9b2ffa66c042", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-2d2e74a3704d6964ff64", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9f45e376ea3da4b17c32", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-44525e439ead5cf1926b", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-13923f8d94a0d0ae4937", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-b30f9705bca57697114f", + "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 + }, + { + "id": "ea14eaab73c72643e734-a7d18ff2f641f5cbf514", + "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 + }, + { + "id": "ea14eaab73c72643e734-e0a0990679eba59f084f", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-d07e0dccd2ae40c36625", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-588c0d140bf9efd60a8a", + "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 + }, + { + "id": "ea14eaab73c72643e734-7d51b759d72f50c2e069", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9aa04acd042f2f815772", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-83c5a739fd19c1ee758e", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1be5ce38e6088062d978", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-266740492e18fc860ae6", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-5201d0b8a57c2e862249", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-40e808dd1c844558cac5", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-691006a324af76b53d61", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-3a3389d22af8979f8eeb", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-c40ad10afeb67ea2e850", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-10149aeb19bf6697c9b7", + "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 + }, + { + "id": "ea14eaab73c72643e734-1c6ef5e75874838d7120", + "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 + }, + { + "id": "ea14eaab73c72643e734-7ebd0a99b0afcb231926", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-dc5e7d775e8ad4bec7f4", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e4d66d69d8df88578432", + "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 + }, + { + "id": "ea14eaab73c72643e734-9c425dfa5bfae0c980c2", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-17eda50816e6fbbbca7e", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-efabd841d061bb9e2536", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1f196ca428edacef09ee", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-4ae95e66ac42d7d03f9e", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-6c413f210385d70a7d80", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-86d59b7185aae72ca502", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9a9e65a49548f6b4d6a9", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-509e6f68a4e4efa344a5", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7f99bc001b5cb7f460ac", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-39784f83c5a20ae25922", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ae72eb701fecb9af3759", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-c51f1e6e8e3e150cf656", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-93d2a37ad53cbfa50f40", + "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 + }, + { + "id": "82e9aa99dafaec340dc9-e1fe2e4b9b734ba3d131", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-f72eb06a65f80253993d", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-7ce46c729250e79cb277", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-150ad3f2de69d36e8b82", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-130924bf85ce0603c3c2", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-76381e5bda48a5ade3a2", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-a0ff15ba8484c82eb5d4", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-1dd95d3d390501835602", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-4895669ba1966f650b48", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ad42062f96fd6eff1e57", + "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 + }, + { + "id": "82e9aa99dafaec340dc9-f3aed2b29f46acf70e9c", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-d4a7ab2fb9f82bf30b31", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-1aa42586b0131c02286a", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ad1af31ee3dfc38e3f6f", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e6fe305f0c0d3313abc7", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-cf1964446ac3f3a005d5", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-7bfca3da1efa390f1d78", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-3bb82b015b925c65648f", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-c0677c484632220c9e08", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-2d734612eafbf347a12a", + "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 + }, + { + "id": "82e9aa99dafaec340dc9-9317141fd45591056bf4", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-48e2f8d5a7ed9f6bb5a0", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e20a77918392d00be03d", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-de4bddf17cef4be77029", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-93ccbb4b069002b19fa2", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-0874de284439b96ad2c4", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3de9b990facdeff0476c", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-749a7d338b2101206765", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3e6382df01316fb281fa", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3bc55ca3eb9f410ec0e5", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-90f2213c5aab99e4e570", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-1dfa2ee5c94403260245", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-86b43820f5b552d786cc", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3dd543ca3a3090d34fbd", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-c8c02cdc6e6c0fc1420d", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-9a4914e43bb12fbeb582", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-769b87498109362f84fd", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3e4973914f06c39b6698", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-083974800f2e8879ae1b", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-641a2dccf8325c290c99", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-4ae457363eab61ca9ae6", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-8194bd99f36b6e951031", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-fb2e3177eb20d90269fc", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-2b7df84230e1938edd1d", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-ab2589367119fda8a5c2", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-50ff4f070fa19d28d259", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-e3c66306c7b25f4f4e08", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-aa481f1919609650e0a3", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-5f4c93857986beeeb8a1", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-bd3d36fb7c393b6fb340", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-711513ba84f86888eabb", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-218ffe39dd11365c7b9f", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-39b746d120824d46ea24", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-7faad1910240a59dd0d1", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-25a6bf8bad817690412d", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b29b1c45e6d1ec961272", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-667bbcd209351537a529", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-69c72083a6301a7b0a95", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-967a82e04705cb8ce7f1", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-4b3a751945fffd4f1a50", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-d7bd4e5eaff49ff3f6bc", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-0130a4a91c9404610c5d", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-6bb9d58f98fdcd85523e", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-38e55045d1be4acd5358", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-3b5e09ff69da4caa4ced", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-83bac7c7daa4e1fb0eee", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-0c5ae0e780b7c4cd4531", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b025eb13913d88dafadf", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-8afabec893b951bc9dca", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-1347f52c5334f122e18b", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-338fd2cfd69b416e5e22", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-9b82c9a55c0a272c73dd", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-e2033bcf8e8df5d25107", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-820a88dbf4c7c26b97b7", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-4bf4e63de030442894fd", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b3c6572e746e10e018ea", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-7b9ff7b1d7be3cd2c923", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-33f5644884ec9ba86bcc", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-2b06e449e9aee6d0450e", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-6941bd46497d1d2ed300", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-7fe227b73432db99c992", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-c0d916d83a69c0da121a", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-bafeb7f5931093c7a39a", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-cc32f7d91ce9e4df9fc0", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-0ebaecb2cd423a62fcf1", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-63d5f364fb9be03dfb3d", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-4e88cd81c30b7e5827c8", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-6e8ac8042e4aa05ddbb9", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-e86d33c92dc30d00cf21", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-b7a4cf05e951b7de5920", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-d8b9352760cb4971e37d", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-8fef1588177f24706032", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-e50eb3463d090abc7b88", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-ccb72602fd5954f2946b", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9b9158caa8753869e593", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-8a3807010e3dda6b493c", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-aa894c121cbb637c2356", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-1a2ebfdf05d5e3422606", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-dacf4da548671cffcf41", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-3fb0d0152310ce81c940", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-a2863c68ee28f3519445", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-9a88c32f828a7664851f", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-0d55461371288f7574df", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-daaefa1bb396ff5f0509", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-f092d45564e8b3510bda", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-643e209f256d1a250a16", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-7fb7121ab78997abbe47", + "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 + }, + { + "id": "c1d78ac5d79cafa26733-b7e30679e943616dfef3", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-41b8387d30bd3355cdea", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9fbdd4ca5d22c59ccd22", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-208f9783e628fcb9f8f6", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-9b25a8ef63de7b4dc979", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-b6eaa1095fe80688f08c", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-217eac71a398847de922", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-13fb46b81b245d60cb62", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-2388222367857a3e66e2", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-13542a5bca0f6c66c1d4", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-55a303d76fff18e9c543", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-aa7ce7a489558e5015bd", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-a07eddfabd5626cd0a2a", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-be81b8fbab088b300863", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-219d49c53f695202afa4", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-7c345ddfdfbc22609add", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-a266ccd310d1805953af", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-a4537e5ee57ecc6df48e", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-8789c7a223602cf16bff", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-3083605efadc1ebb2817", + "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 + }, + { + "id": "7d5f843a3eb7268e468a-d14a5ea50291afe6f9de", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-d8ab6eb3399b84992a2f", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-550cab25cd4472ab5404", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-815457e6e43f6215cf16", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fb5d2acca03e53a05fa9", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-938d058c513b2c6e4a7b", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cc2f4dbeb12688fc0d09", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-13a224af21b3d0914046", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-0139c3c03ae78094f003", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-56fcf9d4ecc6dd2b5317", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bb9a8e784bc0eed2746d", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-f8713bb4e572bbcdfa80", + "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 + }, + { + "id": "fe39740769f1a80c4f29-db015bbeedac5adcbd10", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-19ecc671e1e026bc0ded", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9ef90c68539232ed41a5", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-21cad0e9cdd6d2bfd1b1", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cecc49e625d4d5249b11", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bb05d7f99e674170cef7", + "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 + }, + { + "id": "fe39740769f1a80c4f29-9646aff44447cc995bf8", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bdce42f9d74c3175e0d4", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fdfa7d6a3e6cba0ab22d", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-7218f7cbdbf7c782e370", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cc08e8366aa5d34a9c29", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-80abc0538891ca5f3aa1", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6d04590538d38c42aad5", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-c57605f5ef7b09cc636e", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-0ba87022d3f706fdff30", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fe1595dc54e07363e691", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4297141ebb2129c56d83", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-63c383aab40510893259", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-8b1e8a0ed4dff57437e9", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9fdb2090b41f1f3ff3c6", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-23d2a65968478f02d44b", + "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 + }, + { + "id": "fe39740769f1a80c4f29-a20b1cb4c50409198ac8", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-07e5b86c2ea67d5bfe00", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-021c130be876d25ba481", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-842e4f5ea371dde0e5c2", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-137445c9986c9c51f2b2", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-da0df43eb60cf30984ca", + "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 + }, + { + "id": "fe39740769f1a80c4f29-2200c9b0e251b0d7c3df", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-80f4f73c29520d56a77a", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-24afcb40cac5af9d1385", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4e3c4d42cfd2be629006", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e9de1c8e6c2f74726a21", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-a7b2b5adde5a53dbe684", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-b70a7b7a9d964994eb6a", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-226a392ef76eb6584e8c", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-683943286d8f1c511779", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e87d954b29f0e537aafa", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6c492f1a4ee91737fb44", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-222bf68318bf2fa781e4", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4abcc05151f508b6b38a", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e62178933620bc510f18", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-936b9f3b6aa4eaa086bd", + "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 + }, + { + "id": "fe39740769f1a80c4f29-6af01df3c5e6334b2804", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-37632dea3a3b0bacf658", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6af0c468750891cc0795", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-7c85395365aabb2689de", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4096b3070bc74225ccef", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-45821ce9036c86d58429", + "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 + }, + { + "id": "fe39740769f1a80c4f29-2b3339054c6014e3d92c", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-1f11bfc1f0db92a746b3", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-5dcfac157f8728da6350", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4e69e56ade45d1c34c23", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-df9185e3b4b991a41e64", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-ed9673608bfce2021867", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-24b54879cbf233713158", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-88ac928201db18372b56", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-e6d95084fc692fda4982", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-c596a9468fae531af4fe", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-35933d1aa16aed20c273", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-284569d9920b0e711743", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-f133edb484cefef36fa5", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-b6865d33ac15fe202ee9", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-874d84ca789695182779", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-a4af7d5968980731d353", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-46ec1b4d191ce6ce2b87", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-c065a965bf03c20c92e9", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-5a43a2d9dd07eb718eac", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-5c900727f4df105d31e1", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-48f5ae6cdf42faf667b0", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-8ab1ef6cc7e44699a093", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-823f4e17aad9a4475863", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-7a655be064429dee0a96", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-acc7f1cafcbeef593883", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-4b319da242a0d8c88898", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-a2ac88d6cf9bcb87bc6b", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-26f0718fb72ab6480f46", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-9fe68a142a0bc1358130", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-808e795ad0ae6b29162a", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-7579b31713d2e73709f3", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-b22bfeda45eb2ca888e7", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-cbf8c58deb5fb97b5f71", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-49920d5cdcd992e18848", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-89197327fa985823badb", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-39a5048a03780f5926dd", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-38816d0b0af580ec7ae0", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-fb11c3a2d7114629dfc1", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-04ab8fdb013a043672b5", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-c674c60cca295235cf91", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-461f5dd6653ab5f2a639", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-27a5bff23ff7f1de8dd7", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-497b96f591affc76d55e", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-161d08b4110420b80ac5", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-c204080bd3b07a435032", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-9926a5b91c5984e3b054", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-6cc5ee1c72355fdb1396", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-60b0c86e91e11633d921", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-7720022e29c29701e505", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5cf5d68bdd537fd238e6", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-dc4dd75dcb489b80e3f7", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fde552e9529a19d3fecb", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-a7eecc22cacd33b910b2", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-965cae8eb7530de807fe", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-187c124ce8e69535b346", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-4aa95e812cf8a32b7adb", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-0b25f726ad05ae471db3", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-b943b423ff6eae4207d8", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1de19e97f5545df7afba", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-eeca99dfbfffba631604", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5bb9d55b4fcc0d96aa0c", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f08813139950541c5009", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fb6ded7b3f2a84801a6f", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-244a33407a1a4f812e79", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-532e0d74c736bd1a0a96", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f2e118615ee7bb5a6215", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1a9c3a775cd64374bbb4", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-362578108b38e76fbb38", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-13e3feb76468dac21311", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1bfbe29327bd8d169e61", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-aec7df62b58d89b641b9", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-3f5d5b7cfda98d08d6f3", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-38d36f45d72a4173bca7", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1874e2851c159cb95e46", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fd0415b8257f201f89f4", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-382b12a6bab3d4b449f1", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-bcf78818601a8279511c", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-6919f1e24909ceb2e9c2", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-032298add8fa5c9e6900", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-9eeb960c866cb8e40ae7", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-495621812ca11295f6c4", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-278ac9215c6ee4ef7a0e", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-281de4e437f228cfbf71", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-295d34734b65043ad9f1", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-eccf52e9ad978c3fb6f0", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-997c6976d105bb92e34b", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f8ac31a8f379e827afa6", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-2696dcfa7d78664906eb", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-c987918ce4081b93f4a5", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-ca7249b272a4ee995262", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-31189dc5c67888379803", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-2095690dc9b524b59f2e", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fd3da8b80bde24b740c6", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5bc8d77279a092208982", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-617565d43b891af783fe", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-f9616507688ef54da419", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-26f0e410fe8fbef993e4", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-82f480adbb99a326dbde", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-5125ea2213ff5db2e37e", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-826b6613db8e2561c1f9", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-a0fa0283e2778dc5de31", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-fa9c790ee5f9cddb03f6", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-50d0f3b11ab1c6d2a851", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-58c86f200056ced2c1fd", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-ef8e8b36cd6be9ade13c", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-412a59f5e374b192ab8f", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-7bea54a023db77650f45", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-f2a1eea4a9da71d32455", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-0ba262110508d87e2629", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-89a9d197048808466148", + "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 + }, + { + "id": "ec4e1a8bda76411e0d95-cabbe9eb64dd98cf1577", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-5f6824deb87c02f599b8", + "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 + }, + { + "id": "24da4743f3e5db9f15e2-ec4b2c508a72550ea58b", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-310aaace35717117379f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d69b68b0bdcc53067f53", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c1a588135d6cc568e6fa", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-97e1208644b9fa58b8b1", + "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 + }, + { + "id": "24da4743f3e5db9f15e2-09675477605b25710801", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9e893625c48fdfb954fa", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d6b81653bb60630a3599", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-66a15a5984ee4598f0fa", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d7563229ff93d6112f7a", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d51274ed9cc2dbcfb578", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2c737f670669e27522d3", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-8995ac2dfb98da407afb", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-01938547b760ce9813a9", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-03fd75c773964be30538", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-4e759bd25c03f8a5d10c", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-98f620bde5cb9a1b371c", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-0764e8c8458e141bc8f2", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-59ab8baf180ad899b67f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2bf2947fd3d500d7172c", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-87e5729cd74cd61fb7c3", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-46a350c4c851b9f21238", + "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 + }, + { + "id": "24da4743f3e5db9f15e2-4e8564bdb7bf0592a134", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-17ef0769f5ab192ba955", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-43c293f7c92733bcc08b", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e24f37c60c9773759771", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e502fb517997f1b53153", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-04fe566dc8e712f78ad3", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c1083b5c3aaa666a25b5", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-965d4a265b14ec72626b", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-aad49f66089770417b5c", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-afaa58fa5e14ad72db35", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c460f1702b1887cb0943", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-eb991a205aeec0eecc91", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-bcd222ce2c4830ef345e", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9183819e25f74564c41f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2c757941b4feb418e86a", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-342135d4e67724c3cf83", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-97ae305550aa393060bd", + "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 + }, + { + "id": "24da4743f3e5db9f15e2-7a2bffaadd6727862592", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-fa81266d048708984784", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9b9974717b4576aa1ae4", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-58b7be0d4b52aa9fccb4", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-fcb2ab222414744b8ea5", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e6130ef57b5ab5661f42", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-ebadf97bdc5e9f45affa", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9ee63e8b728f62bd983f", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-021200f38ed02bb50845", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-03c49c3e845e96f8e76b", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-1bf7e7b8230dff7a356f", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e1ffd301af299b9846be", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-d1cba7c810d80b340f02", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-b18e0bd87418016b019f", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-f640c192434bf9a64a7f", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-af04f2118c29852ac4d0", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6bbd26e23fb3429993b3", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-78efe4e7a850b2a90ebb", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-dd98a66249e18d35e4ec", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7e56c82040d8213b52fc", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7587ab0e8e449207ed24", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-5da1a688dbe2217facb7", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-489c3bd67ceac85c7d79", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-4d1c0bbb0d31efac6702", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-83a5f6f72a73e749b6fd", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-c60ed5afa38f7991685c", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-1961de75defdc952a8f3", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-351ed5a2908f4cc9619c", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7954fe1c578a54eebf8c", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-36154f67953190d1bfba", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6522dbb08c1b075a5ec0", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-76e298b978895f180911", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-77285e408518bdd6dee8", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-c8f1d687675a279a00cb", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-3d38bfd5b7b08646ebfe", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-70526633595037330da8", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-e00d282a9b13f205b9a9", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-ca150c7e341afc79085b", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-de68c38b7c4aa90447d4", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-4bf9b7e006db011964e1", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-b81bcd76f642b8cd1cb6", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6a1c655a7541e2c283c5", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-33ab58a217e5ed46af64", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-6c3e26795bad7ad08640", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-081e4a3c2efab5a6a4f8", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-48f3dc84a4b45ece0f66", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-bd8e568d3c301593236b", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-a20205da01df1b6d1275", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-cd03a72feb502b43128a", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-c084c9d9f3321e48be59", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-291a97e5971de8da34fa", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-96ad9b36215f1db666df", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-0ff5f41421512bce0682", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-85d3c1a084877cb32e68", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-9a764add8106b570a9fb", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-4f6c3e8455782e5592a1", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-321e89c016aaf0a04e89", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-3835036f94dea4e826e2", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-cda798777baabd4bf688", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-685f7f019e46ba558b9a", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-640ede7d3ff202fea200", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-254917f54cf2302cd6ae", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-36849c7e4b2167768c04", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-ac5d5c862592ff76b6c7", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c3ffd08e95c46586ed24", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-46ca3a1867d4e79ccf78", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-330b06a4b4886d69f8a2", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-7ea574653c71793cdc59", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-494fdf7a643287f6e9f6", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-a20b9efe52074aba9a9e", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-f720c3dec109e51e7e33", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c7e1c0f20ca436a64e31", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c10d09a36296547cce19", + "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 + }, + { + "id": "f12e0488909e2ebf88cf-65b87ddd974d9095cd99", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-f923d3845a11b464c735", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-71e88fe06828c0aaaa52", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-0e43bca78fe1615e1188", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-74b76fae26483153575e", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-f81f74c17d54e135812b", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-cb7cf3d37546dfaaa25e", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-ad243930eba7bbfca9ec", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-4f06979d10a0cc73f0e4", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-73b72e27dc0e279e1dfc", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-a391ecf6be83e360d5af", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-9886e61b50b0325f00b6", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-7661cdbadada621ddbdb", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-534b6a21f22d52437946", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-964c3e167f81d6c4b540", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-b8af7f6e76d64a404611", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-26e289678f8318df9985", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-a31d40ad896888983990", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-41f669bbff76dba08542", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-94ccef7d1b2712b3a8c7", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-0acfeccae2fa10a364bb", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-804bbc5c45a32217b23a", + "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 + }, + { + "id": "9a48fcf31fb0bf73c484-e1687b8c29a364456ced", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-9de93a65641998f55bfb", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-ae29a326f7d6b9244c7a", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-5642c616032ffdffac35", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-75b1d9674a6663bf2d6e", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-1e45a2a5dde8e9ffc1f1", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-fea8a7011bdffae81cb6", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-4d2842dff07972329923", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-5235450a56f738efeecd", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-6d06c3705c2addbb8090", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-1707b8b14a6deb4b2b1d", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-c052ddece9958e0555fb", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-1723a11b47d130206b98", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-b93e8a95aa929ea2ae0c", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-60bb8e6ab68260d8c6fd", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-55abe99fef6857550456", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-78fe676015d6e8dbc0d0", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-a24e837c0a70d9648453", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-802ef8362a0f403ae08d", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-70abbec3c9dd6b888e1c", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-c0ab35af2770dd5f4806", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-e72fde2e2a57668fa47c", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-a4df961c9062ebada00d", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-73e6bcb78301864d09a0", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-0f38da640b1ce0c5e360", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-08a820c1f1e532774cc1", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-0a6080d5d9c551bbbfef", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-d47adcf0c29980498c19", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-c1239d4ad067319ee2a3", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-229449f9f5a2f8fa7963", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-52e7670a5b3a053c6e55", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-7ddc0ea00c170012b4d6", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-dbf437be2f34861c5a0e", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-3c389ca847ff1e4c75bc", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-6542b91dece2a74614df", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-51b208ac054e2eb00b26", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-4f6db3993845b9ba2985", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-bf0574101b74e333abfc", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-b8e3d4f14c5274942e99", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-aa029ef04ccaa364abaf", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-884e7e97cc7f4601b9b1", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-89a5f36c70aeb1aeb725", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-6e80e6040b5d820ea851", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-89b1e6f236f0b07b34e9", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-76c423a2c23281a89f4f", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-f1b89a3a449ec92c4a02", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-846a43d5c11f461bc706", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-6fc43c2ad3b16ac57feb", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-923d4b452977986e35eb", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-3751522702f6c4040d89", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-7c1ede28fdbca2fdb036", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-2e71806ec46cfa3c8830", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-308b7034593f3aface7c", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-824de270447cd0289399", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-2e405967fd041e7bd63c", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-73ef3504117f77184a3f", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-273a8c96e455bc2cb3a5", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-421ad6f29b1e4edba558", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-9848ba9b5bdc87b7080d", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-fd0af30740777b8fa6f6", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-caf25f6ee3ed380b66a5", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-1694c548d47a5dfd7321", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-4a613122854d4efeab25", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-ce9ca8b3a37a93a751e0", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-a86fc2f76d5a0e73dc92", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-ed069932d1cecddc62ca", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-9a9f8fea7676c3fb1f03", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-7bb2424006b234f72e6a", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-f7838ff686e269e64cbc", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-22b53afce3b44c0e3b56", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-7de925a1d5f347027a30", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-d4bffb27232bd134e0ba", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-115453f0cb1f2df25c13", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-576425b00e3b37a5f55e", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-6ddec59a6b7a73444874", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-c4a665637742c22fe6db", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-05c7aa4a035cd53f615b", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-ff797d35cf4226a8908c", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-b321c5b060f24c0dcf7c", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-86838248a63b8cb598e4", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-f74d56109a0a98dbcf37", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-f2cd78f5c336b7b5a29b", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-687bbd5c29aeaa2087ee", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-8e37462e4a700a9d032d", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-8b838317977126c72896", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-c162cdb14c052116404d", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-0b01ed5f487c653ef5e6", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-3faf3b0b78cb6e5a7916", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-3cc483840fcb60da6de7", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-886e669450b0aa293cc8", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-5d9e035f106d302fa65a", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-850f54c586f39ff9ed15", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-b9482406e41527269426", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-472f4ce1e106982a41f2", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-e4b709b61462b8d189d1", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-9d3f428ef8c764b1ff11", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-6fb2012cd72d02b2a069", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-17106154f47c826afcb7", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-49817d29e2e8721cf6b9", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-0aa0a59420e90b9113f5", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-cf318af31bbcbc8c0d29", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-7172a28011c10712e8f9", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-db2b94c7c74a6265c7e6", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-ed084452ce2ddeee614c", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-deb5a4dc1d9142fb059c", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-bd60bf10694d5c9d5bc8", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-9bc90e10e6b91381b1dc", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-14c472cf2848797472e8", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-d3fa95cf4dedc7407cd9", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-fa5dfd957b26f3982f9b", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-84eecbfcd48fd0b44da4", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-7c987ef852f16f3323dc", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-b1e49c1b67e35ce90df3", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-a42dee36a9b3d9c4fa0c", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-bb6dd2a13ef876f27f20", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-f4bc95d33fa3669f089e", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-821001884db4778713ae", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-180bf4aaa10c590bd599", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-e6a6a636533e1ae93dfd", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-c80ec0bb00165ef911a5", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-1ca51d9b23c4840440c6", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-7529bbc5da7ba02e9881", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-249074f810c94193958f", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-5d6d4df808eaf0e9b59d", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-2fea8a03da06a8d155fc", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-84eebdf7a1b26709a4af", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-c6f3f4dbe1114df7bca4", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3b6abffecd638d7e143f", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-435c729ed77736ac49bf", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-b1d56ff1e9d1586f27b1", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-f48f91aa1d16a05778d3", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-2f0d8d05fb5628452b73", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3237a1637bb73b6d11bd", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-87851356a1e1b9a04832", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-7a52d540da49d844c3dd", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-2d1be2095bee8967662e", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-9e91549ca39177fdc341", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-9c6b842be6a0229603b2", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-da73608d2f06c5869eb0", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-04000d17fec631057431", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-eafb41732c2d02fa92d6", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-f1387f78049e2f96216d", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-04bbff86779db8d424a5", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3cc599e6ea966ac42f1b", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-6c81f2fe32d5bf59df14", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-01382f9e44ebfe71cd1b", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-7d7a52a1212aaa3903f9", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-e0bc3bdb9684a0cd782f", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-135d698a416df763c37a", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-5d1ce52c24eb280eaa53", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-cde9321fcd4606c1b6fd", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-3b4d510589021541d752", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-cf920f57a2f13b3ad575", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-57486584167b26522115", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-00fb29fdb678665bd82a", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f41eb20d274264176967", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5ffb3fde2da7d4420c6c", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-bf7338a3096200f9f48b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5d99a0f5b38ea58db833", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-15130b33d5a769fe6a32", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f4a165db0eeee2fbb2fb", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-1e6f34f81abd19db2f8d", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-f5e430ce64b390617ee3", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-dadb0014a2da497a555c", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-e14fb1f8f441e37f3b6a", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f5fb5476b00f686e7097", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-6ef2f1516fd5d9e51fc1", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-1142eddf3eb99d81c770", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-6f65c65f97d09691ecf3", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-b2bb869e9bfc30126140", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f7de42ba4922f372e409", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8b0033bf3124c2381b88", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-ee91e94bc145ebbc752c", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-0a784e55b980e4a768ea", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-53895d4a405ab4764718", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5a3db1f978360503899f", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-ad82945116d93adc0ee9", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-34b194f9407279f8831a", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-9dc273025bda0344f5c4", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1ada9c348b31da0129ce", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-fa685e4dcb072c9ea0ee", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-884c6de7c5b0cd3f6143", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-8c085c86b98980387cca", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-1d032d41a8812068669c", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-88075bd9b821bc49ad85", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-e60dc36054298fb611da", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-a97693c8c3afea09a84e", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-878e0cb15d6a04d11f7b", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-7d1e13e2a9ee5204d11b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-7c59dad85dabf535d30b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8310d1a5474799c482fd", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-22b4165ec09c3e56b7e0", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-91e7fe297e8a037196c1", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-3d9bb69b9a2c4e7a5f37", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-047950c0a6d89c18dc10", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-9682b6f0bf28f0a6701e", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-4c2944013559cfa3aa5e", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-2f87e96dc17cd24bf360", + "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 + }, + { + "id": "d506eaa4732c86ec7b9f-00da5bc0a7813116c372", + "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 + }, + { + "id": "6e198c9007101abd57b5-d666f9cbd2bc867bad9f", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-dd5a610bd634cf860947", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-17ad59cd7db68e82d4e2", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-745d515c00e5ef36e018", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-cf379c3ac3906fdbd530", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-b7c2d17089053cba66fb", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-903dd2547aeab4333b8b", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-dd7bc21d13c67bacec65", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0cda73e045d032d47ee8", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-2b2f887e4b2b9c1be8f0", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-c5b5c2f93a4e9a66cf63", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-357f232d33a60db07e3c", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-7785bf4b3b17c1ff68a0", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3b960308df208119cf5f", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-a39e2d52b8853c5c18d0", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-65fd62ceac4a2b0de679", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f0a0ba282ce64661d749", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-544d30d9ac046c59b7d8", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-019ac6cec34bd5492707", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8f9ac72827bec9ca6d46", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f9edbb240e681f54990d", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-925ded2c1bd757ab65e0", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-494124c7cb25ce9c8484", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-08ff1fea641c1071ce3e", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-5fc0cb0bafacd337621d", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-bda80a9e217d5482e64f", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-42a6aad1e0fdb0089e55", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1d6fe57647819834649e", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-76c4d4bf464d081a3736", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0f1cce7dc1de17a45a59", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-db50125db4f2a490fdbe", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-bc0f9dca801bd308ea8f", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-67f07edf6c0a08c6b68d", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-14422e8869a16392d3c8", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-58025407c8f1521df7d4", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-74c1f1904ce6d8baadb1", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-2ec13de1e4838fba9146", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6a86cf5a20b7f1eeb2fa", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-eae7ba2c99c1bda33c80", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-7525b67820217feb9c11", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-681bae4b93740ef5f0c5", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-90603a7bbeaac3ebac92", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1c9713c42a024b95bd44", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-13bd01f6910054eb3295", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-88dfa403dc0f8ba0f199", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-93362782d6cd1c9b38e5", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-151d89deff8c82884589", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-af17e6f132f3601b9340", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-fd13688753dec32d87cf", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-08bb1d125afe61dbdd5f", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6718d686298503531939", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0443b81b66ee434750e0", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-67266454faaf86e9f82e", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-30daf2d7d1aa4885ac63", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4939a26ab7be1b67bcf0", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f95651ee1387c941a464", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-54aa82fad20e6cdd81d7", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-88ef3f5c7107b92df586", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f5a885749ae7733db165", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-18a5161d5a026f9fba04", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-98ca74f8f55d4b15d8a1", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-50cee2adb9a3c61f0dc6", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6bff7e83b5206fa9d91d", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8173f024a9d58630ef0a", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-da9ef20e377375a16f83", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-07b831b27287c07fcc40", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-691d00f15d0081cb59f7", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-845ac433ce41eb556d00", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0a674a144ccfb1d95b83", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-e565aafcc819b2450df7", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-29089ac1a04857021285", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8ee8efd4c48b9758c274", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6acbb8df373136b70a54", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-07b30dc9529bcc05872a", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1d4a2e7780e6d0550948", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3db8330bddd94096be58", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-38ee4ebbf8170b376a1a", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-51b82f8cec6133b560b9", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4d2164eb08268dd10fa6", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-9bf6091babe12c0829ab", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-714d3a7f292b207efea6", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3aea2df8043c6a6e28a9", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-79d4c0f92c8e7ce5074b", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-e83b0e3f4aa0610fd15f", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4d1ddd2034d35cc4620e", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-524159ddf174094337a1", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-ba7af307dca325c42461", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-833e9ff88cc7391a59b8", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-6782edd72d6da4a4ad8d", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f252bd2fc447577759b0", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-3cfca19d21391eac95e4", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f888935069d847b893e1", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-6e57082f8837ec98eb4a", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-d249488159d1321fd2bb", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-df992af2e935cf8992c4", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-80521267c3361388a69c", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-32b0ab4acd28e0f0c843", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-2a9cd3695fb54d9983eb", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-e7b06471c09b919d19a9", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f9ef3279fa413557bf74", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-4493fdd9f9a0b065a5d9", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-ff9db48194323087ff35", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-b3f7622fc945984018c1", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-9007396b1c807988496b", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-7720ba65254587e4220f", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-0dfab8dfb052a78725c9", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-2206320b5471e792b324", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-42d36054a79412ea814c", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8a5fef92ae9112a22e17", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-7c15928bbf9cf5446364", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-3e105514fdcdf2109560", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b17f3a99113bcd921376", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-5a386ba920946118f5b9", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-f152343084d96e444c25", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-19e34f584147a850810d", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e6b47b2e4f1d89fdc1fd", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c54ff96a656f8f7e0614", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-209d6e601169222401ec", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-0224c5f81d88e9a76abd", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bbf01adc9fea833a654f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-df809aca00e2b669dace", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-016cc1640e3b3d043bee", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-07dc4321a38968280cbb", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-7334ec778cda78e83768", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-4a0c98327b25b0f53349", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-3d4383aae663249070b4", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ac1f881dcd7c9ea6b614", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2fc6f4437794b5fcae1a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-affdcf01df5b548e74c3", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e69a2633d1da5da0a033", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-eed34e3a1de997f80105", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-6f3db740e84bd4583de0", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-75a2ce3c50f0326338d6", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-40d428be335e78a03d78", + "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 + }, + { + "id": "bd8b578824fda6d824e5-1e51854f9804aaa89760", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-f0bedbeadb96666727d5", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ef9c82e81e4bc84eb35a", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-a206e4dec77195448b2e", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b6a8e78c8bade555f99f", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1da818cd320f200493dc", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-37e8784fe2be118a89cb", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-baf78a292febd2d0253b", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2f67378d9be913549ee4", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ce42453036328047efb1", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8354c7d516c210cb683f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c2c4c0e141302c3cef1f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-03df75134609c4dfbf10", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-23e94238a1be63a9aedb", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-306ec942a307ac4b332a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-27ea66e30846c6c35d1f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1ff068f72f09e1062c71", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-49268197eca684b03b23", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-45d66a58f8ace121aa3e", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d55737ce84e01c268c81", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-de5ebfc899aee6d78694", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-80a4fc6eab4db076a7ce", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d11efb83fe4bb3c07013", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8b874818fa453c7e6f49", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-644e384fedb167647bc1", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-97913b921f13e91b4542", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-315d8c53bcd83acda5c2", + "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 + }, + { + "id": "bd8b578824fda6d824e5-d511fccbe7e54abf3fce", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bf9ed48af22e7dec6f9d", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d8cac70b11a66ba978c8", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e0d22129fdcac1480ab5", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-75861334d0fffb96d413", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-4d9c22a343ef35f5b877", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ae3ab743fb1aecf74832", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e402f7c34fc93b9cb6be", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-946b1205dfcbfb6f7daf", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bd0e7d1620bf7e83e671", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-54c89f9444bb550d9372", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e0913a2d6fc2540d8a18", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-03dbb2c377fe45aa14c0", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-066d3480dcdc71e8a4e9", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-18cf581403b35016dd5b", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c7b04385144f290eee56", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-18e90e6d63836e36b04f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-350e2e7d4721dc11ee0a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8ebec3e26df820a018bc", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-da28a74d360e5e5f4da8", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b87e2eed66add761c939", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1eb214dd7fb6d08cd588", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-a9c047aa7f9899ee2e91", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ed84cf26fe663abba84e", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b975a9d80a73ee2c5318", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2325734fcbe9f19ef38f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-53fa73e3d56972e17fb4", + "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 + }, + { + "id": "bd8b578824fda6d824e5-68d9c42770fb755ff944", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-bf645b1a65cbfaea5769", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-9d765289d32be33b1358", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-aa26d2ab16bfa364ede5", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0e05941de94496050665", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-07b5247e88feb728a1ea", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-c585b499b392d1f3125b", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-807c73d105e8d88f3691", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-3a8724253f4ed9d64051", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0c1741b96b329426a59c", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-842c1a319c8ec887e2da", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0e3cc6ce8bb29447e4aa", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3157016a1f4a564e4e36", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0bf30ca101daa48f2926", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-f15c420a1fe6dde01ad5", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-d062fb6e304335da8017", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-ab3a301f236c4211d0b0", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-db1474abf9d021d54190", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3fad5bde9035571dfeb1", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-527a6a05cfabdad5e934", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-06d2174f2fcf7425f220", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-84b620f68a13175455c6", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-65451ddd2f6fb97e5b62", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-91327ada1dd05e2a6298", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-ea62643a3c6b46fbb710", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-122f023f6398972e230c", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": true + } + }, + { + "id": "ea1be0d464ef792edb71-651f98b0f143502c508d", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-65bebbe49c153c2d5f16", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-51c0c54a3382808aa510", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3670c81ddbb8cd20a30b", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-9d3c02ac24a72b007bac", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-62ac1fcd49c58719b731", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": true + } + }, + { + "id": "ea1be0d464ef792edb71-a0a212ed633e0fcae542", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-fdf8e58e63293f008154", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-6749a7d57a0a08031b98", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-c71eda7665d7fe280226", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0f9982e28da4776b41df", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-47bf44da43f7ea630c57", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-94a91f70513a4f3a0536", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8bed1f155fdd13a8d676", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-76ae798ce585defae260", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-940ea42ed81a2e76857e", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-fe6258362fcc32df0641", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-3976dbe5125baf9596ea", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-e85621f95b6a8e48ca8c", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8aa46f4bdea9ab2db828", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8da0c6598ba3b3f02663", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-d7bcbbb91d28521d7e10", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-737ee111c8455e9547dd", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-0a0f67812bab08126d1c", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-dbbe30e49f81e686c544", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-81ecbd7fd933b26d5381", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "webkit", + "status": "passed", + "retry": 0 + } + ], + "reportSha256": "393bc2903dc8efdec15b1f0d11c3aa1e55f1d03bd1048750da5e81ac54ae8e15", + "supplemental": { + "stats": { + "startTime": "2026-09-11T03:21:09.800Z", + "duration": 9864.545, + "expected": 24, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "candidateMember": "artplayer.legacy.js", + "candidateSha256": "11144499ad0c37ee1b2719992d9e9836b7d5b5abd7b37f6aa4928aaba05cc924", + "displayCases": 0, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "nativePip": {}, + "cases": [ + { + "id": "dbbac41dc03fc4f485ce-1ed76b5f6a82de9d068b", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-3cefbcbec7deeff53d05", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-69355e4dc46467b0a9eb", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d94e9fc7c4dba97cc53f", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-61c4eabc80173b1e442a", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-71d443a2b6af5518b178", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-59cb2417e70f961c50e2", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-9c1d85713fc8613fc6fd", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-7c6a370020654bfcada6", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-30aba1a1bb1b8501b0db", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-15709a7d6ee1e1e37d05", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-1b85f275ededd6b4ce29", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d7c211503e05f9db4594", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-f8c63f06543266f0373c", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-55df032d48093a9a7a98", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-43883bd2151838bff08a", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-96cfaa6a8f4b9da28c64", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d322bdc5916e8bb4e882", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-5b6a7c315b0b983e8044", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d5dc97a19584f2c0bd7c", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-509d99c428ef04fb2e49", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-fac2aa15d600bc1bf552", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-5b23a746569631c03db4", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-bbd046deabc0ca1172f6", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "webkit", + "status": "passed", + "retry": 0 + } + ], + "reportSha256": "59d4510b0b684188b17e702fa4a03f173aad04bd1bd89ed614abdfada684ec5b" + }, + "combinedCaseCount": 1143, + "combinedInputCases": 243, + "coverageNote": "1119 full-suite cases plus 24 supplemental closeout cases against the exact same installed artifacts; source and existing test files were unchanged.", + "inputCases": 219 + }, + "packageReportSha256": "48067d9b152bb10e8f3dc5505308469ab43a39e496ed1850f056cc69b273b254", + "phases": [ + { + "file": "refactor/baselines/hotkey-validation.json", + "sha256": "7dc63c1d525867d8ea5b58c91a90e301518194922f6f298fb03bced3cab31dfa", + "status": "partial", + "scope": "Historical intermediate source, not the final installed candidate." + }, + { + "file": "refactor/baselines/input-listeners-validation.json", + "sha256": "c0184e68e3dcf1fa6a974477eff37d4a6205d108f26d884124d4220725d43a0d", + "status": "partial", + "scope": "Historical intermediate source, not the final installed candidate." + }, + { + "file": "refactor/baselines/pointer-validation.json", + "sha256": "2136cc59bb8d57b2db29762342a98ffc34dbf2631faf8febb5633ae64132d8d5", + "status": "partial", + "scope": "Historical intermediate source, not the final installed candidate." + }, + { + "file": "refactor/baselines/gesture-validation.json", + "sha256": "0e3fd9e5a70265e84be71ffa297a6107fbfa71be2c21bd45fe47b05cd70e46f8", + "status": "partial", + "scope": "Historical intermediate source, not the final installed candidate." + } + ], + "boundaryBaselines": [ + { + "file": "core17-scheduling-baseline.json", + "sha256": "d4d62bad239f6103616a2c5633bdf2db6610bdf2a4ee72b475713b967f3672a9" + }, + { + "file": "core17-scheduling-first.json", + "sha256": "ca20ee17a298ad9466192aacfcb5d9aaa9fbf4df5c2a90482dfad9830f32d8c2" + }, + { + "file": "core17-scheduling-second.json", + "sha256": "7a0bd62f987cd7d1af8b5c7c93cf6582bd0e36c1abfd779aa317fe233f184dfa" + } + ], + "build": { + "logSha256": "d120f14f316f870fbab4991927f5ee26fd4eda28e68751e9160f407499249dd4", + "i18nLogSha256": "97de28a00bf87ddca35a198c5959537f6946d41e796b4361e51aa2630408d7c9" + }, + "resolvedFindings": [ + "BASE-DOM-16", + "BASE-DOM-17", + "BASE-DOM-18", + "BASE-LIFE-23", + "BASE-LIFE-24", + "BASE-LIFE-25", + "BASE-LIFE-26", + "BASE-LIFE-27", + "BASE-LIFE-28", + "BASE-LIFE-29", + "BASE-LIFE-30" + ], + "limits": [ + "The complete current core/chapter suite is verified for CORE-17, not the remaining ecosystem refactor or release reviews.", + "Real native mouse/keyboard playback and desktop RAF/iframe behavior are verified; touch payloads, mobile UA, IME and screen orientation events include controlled paths, not physical-device certification.", + "Physical iOS/Android gestures, scrolling arbitration, OS cancellation, rotation and safe areas remain REL-03/REVIEW-02 gates.", + "Native once listeners keep their bookkeeping until explicit/owner cleanup to preserve callback identity; duplicate registrations keep native deduplication rather than reference counting.", + "Custom targets that permanently refuse native removal cannot be forcibly cleaned up; failures warn and retain retryable records.", + "Public viewport utilities, click grouping/reentry, Emitter ctx semantics and historical TS consumers are retained; only document:touchcancel is added to the public event map.", + "No new dependencies, lockfile changes or major-version application in this task. No push, remote CI, publication or full-goal completion is claimed." + ], + "mainSuiteTests": { + "unchangedSinceFullRuns": true, + "evidenceSha256": "78202b0f5e7beea9ac74d239c156b2f63037961bc8ed82e658d1cfb538d6a16c", + "tests": { + "package.json": "2d1d7d9995c25879efd71f5fdbb524bd150e4c58b75c4e1a2877fd55b2873e66", + "test/event-scheduling.test.js": "65faab59cef6223140808bc310871853610fe3944ea0ab882173037726ddc258", + "test/gesture.test.js": "77235aa134d380a2bb39e572e41bd33b02f6c86ebe72426e55da4b00a5701f4e", + "test/global-events.test.js": "12494982e1846b6d6f6062eb209b7c1218c87a8b2ffb8342b5515ed91da2d337", + "test/hotkey.test.js": "b647a4552ce43591f532d6295bf6d2034d7c301a2a9dae88cdb1b77e651ad5b5", + "test/listener-registry.test.js": "07dcdb1945e530a3928b28a3758d22eca0db70bf4a00dd7e0527a56ef407c133", + "test/pointer-events.test.js": "8eccc6b72f025183cb93f1bbc2c03e42a98e1a3bdf6c03e8609c1b2fc9c2ea2d", + "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/emitter.spec.js": "abf5a850835d1a5580d611a0777c0cdf225a6aa796a63b58096f8646007e5870", + "test/browser/event-scheduling.spec.js": "4ebd5dab23ca8e49580bd1dc3234e612cbae36b735c7c9401d168059eae11c5c", + "test/browser/gesture.spec.js": "9301a91220e5cccf1023918580111bf5287f811a51c0b51e7ed71797cb018575", + "test/browser/global-events.spec.js": "67ef2bc32419f17bb10ff40f7d9e542c110f2202028e5a17d58780e2cc6cf5f3", + "test/browser/hotkey.spec.js": "984e042d277da6ec092e5a16053bef0f2a144a83868dc30cee82a696c2adfeff", + "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/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/resource-scope.spec.js": "0196bd9943c1ce2f6560f87156cd0de47606579c1a736bd46d4943179a121d3f", + "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": "0e6a9396e329bbd055afe14da2e029c08881d09454aa58c8711476a690a44c14", + "test/browser/subtitle-lifecycle.spec.js": "ba91719ccdc9e539aee252d80deaba622fd6e5cb30cdd74697658af1e49dfd58", + "test/browser/template-resources.spec.js": "993ce9876ae9d49f291af4173ffa34276f9b8972828e8d42b8789c5ee512ac6d", + "test/browser/utils.spec.js": "e7f1739938791a6d19ec2cdf544f57c69ad7caaaa6f379128b3676d73d8611b1", + "test/types/events-source.ts": "504d33f54d995c245ea759a08ec55085f38f22707c39e45d26ddfdce261911f5", + "test/types/gesture.ts": "3fb8fd3d895738443bedab2c00b1afda1009fcee5695555d25b73b9bcea61d8f", + "test/types/hotkey.ts": "bc08aa59a8359a86e49cc95f880ae09d5c90a501d4d0ddae7d7467e90b042ef7" + } + }, + "publicTypes": { + "file": "packages/artplayer/types/events.d.ts", + "sha256": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "change": "Only the additive document:touchcancel Event entry; the rest matches HEAD exactly." + }, + "pendingHandoffs": [ + { + "id": "BASE-DOM-01", + "owner": "CORE-23", + "scope": "Control Tab accessibility remains open; CORE-17 covers keyboard dispatch and editable focus, not the full control accessibility pass." + } + ] +} diff --git a/refactor/baselines/pointer-validation.json b/refactor/baselines/pointer-validation.json new file mode 100644 index 000000000..dc8155f9c --- /dev/null +++ b/refactor/baselines/pointer-validation.json @@ -0,0 +1,1428 @@ +{ + "task": "CORE-17", + "date": "2026-09-11", + "status": "partial", + "phase": "pointer-interaction", + "parentCommit": "88aef830dfb583294ce29088d0ba92d9cf522d05", + "source": { + "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.js": "d6d2bd612daaf6c5c6e982158acbdf724b16d3c35bb5f1a5c923284665a8de79", + "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": "a02ab41654a963e06fb2eb206cfe606cebc27252ba00b3fc2116ea232c8d7d51", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "6856d98530877b9458275d8e064a94a81b9e2a4de079cce1a83e7cbe71e5ab8b", + "packages/artplayer/src/control/fullscreenWeb.ts": "e20f8fe9788738adfccb21e7bf248e5e8068312e856bb2626d05fbb20cfdb65d", + "packages/artplayer/src/control/index.ts": "ce23b79a0a40f22bdd8ad5f461d6b0df9366c7e4ab78571e0c67649f6e6d38e7", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "9299d785ce21b16dc9edbcb6a803f8748157ed16e1924f461bdbc4853adaa5ac", + "packages/artplayer/src/control/playAndPause.ts": "e65461f5bf29680f12b7e0efa7d44186f07bbe9936247a9a220f724c9d9774bb", + "packages/artplayer/src/control/progress/interactions.ts": "19d6f73c21f75daaef109247bee392d82b46fecffd04be0944386c307496b250", + "packages/artplayer/src/control/progress/position.ts": "1008c5129097cd2c51fefb56e88e9df6fa07f09ed5f4492505da9153d8284cd1", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/progress.ts": "f0876ddbdc01f812a5a776bdeefdff8dc52e557aff684f99b5ea7f6bfc8c0fb3", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "430dc1b0283bc8a5c5396539b291dce1197470611696b32fde4b2c56d2db6b1f", + "packages/artplayer/src/control/selector.ts": "5d946c36d0308f32e08dd0e189f0c959f738ed7ab521230833c76a5bf9ca6478", + "packages/artplayer/src/control/setting.ts": "63e9824ffee2221ba82be9f2bc430b9b3133a2186905fcce2a61b8aa946a3d8a", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "7fab47c7106efa51aae89026af335f74d9f3ea52ef9864ec2801d0ea2deffc4c", + "packages/artplayer/src/control/volume.ts": "b50d1a5d2697d6440ac0f3d82634b13f7c2fff00c185a1adf4451ed8ba810709", + "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": "911207b0a3a9d4c2d0ef10b65ce7ace67e29e274fb922a8679fe818cf043d08c", + "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": "9dff7ee42c0cd1a9ab37a5acd9788b30ad01455bfd2f3abc2f4e1f157bf16c89", + "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/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/gestureInit.js": "a5dcdb4216c8e3544fc85a1b4d3ebd929ec6f7d51ab17f2cee713030ae7ad464", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "1d57f919a8b9e35a935846f7243b8a84e636f0f5e255e27062b1084c36555c61", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.js": "39ac053f68e13a333ab778a62ca46b45478937a56cf32f1caeefedb510fb1bee", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "11342cb9c97c8ff728bbf6b47e58ce93a43062d4f69cf6cbbbc0a6f8d086c8fe", + "packages/artplayer/src/events/resizeInit.js": "26fc9628490e6c45ef741e7bc7c1353097b21da1dc83aae65dc80783226e36bc", + "packages/artplayer/src/events/updateInit.js": "1b4ef85c819ae68eb0de1791241b2c3d4e22bb108746518fa67f7c322591e55a", + "packages/artplayer/src/events/viewInit.js": "2b4ce508812b8f03cf5801a5e3a7eaa4a5a8b05d6be500d217aeb6231fb93a51", + "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": "3ef720aee403e6b7baf1ab472dbdd16c671f2d691ecea48ff1c25ca1ffc66296", + "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/index.js": "cb874ac34fa650bd364b3fef7eed4830bf3bd47093097ae7ba0432e7e64b1a10", + "packages/artplayer/src/info.js": "6dcdb4457d63ddb74fb6268df64522722420d6c0eb7b1654d6fb7703466d3b8c", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "30a4354e89f96a10bd15e3b94ce03050286d5cb4641b8f951fd17c0724afc238", + "packages/artplayer/src/input/keyboard-focus.ts": "9f49538e93c23e07a448a8f9c9773cbc2e199c6d86e7e0adb59236ce97a07fb5", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "ad542779ae4030c7619b5874fb33466cbd45af5ddb72d3ce984c09f54b24dccf", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "19a89de4ae22cb57eea7302265ce07422d12d1aea5acb99deb44fd0dba351a13", + "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.js": "4b08a8f9fa69f71d054cdf1508bbb9e92c075c8df1eda0fa8a79efbf08eb8c40", + "packages/artplayer/src/mask.js": "094162e28ec76c81f73bb7bfe276bf5832080ffb7aa9d9dc9dc013479659c2e5", + "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": "5532f57129032a9685305d0d319543146c3e8af134ac12c8aa521cca9e83a6c2", + "packages/artplayer/src/media/hosts.ts": "7129cb93290a250e932464b71a4e4abce8a98e83935d4fd6c36a59fc6357b6af", + "packages/artplayer/src/media/playback.ts": "b0e8ae22f2660249361bf05bb2333685e14f5a7ac3e9ba0c62ee7efd38338b93", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.js": "72e97833e0499993d8d133111e32f32f031b911426117397be2003e824023664", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.js": "b9ce49489e75045b6a1df4d8ed28f123c1b105ac4c04fefaabcffe4353ad004d", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.js": "c873d587ff71e024cfda5b5464d0c70a09a6a319da3f18fbaa7451a16c9ae055", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.js": "93e641dd760e8f844a643a0b7d8af92b73a7f205e55087d9501934d218701bd2", + "packages/artplayer/src/player/currentTimeMix.ts": "78c749ec4dc94f4a3a0ce02a87156f07894401b64d12c6c7c3cb1192ff266902", + "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.js": "c3eaeab0aa5015a51dfeeb4de6f25b02b8cd66e1f8471940367d628b5fd0bdec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.js": "9d1d9d276da2403a580498c62f947373e000d9cd6e4bef5831d272c3055b5592", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "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/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/posterMix.js": "a96b0a9f5817919e373a5a55b43fe7ea94af357051c01ddd6ce9c68bc932ecba", + "packages/artplayer/src/player/qualityMix.ts": "8dfcb94f695cf983f313f00abe1aec183ceb2af4b398fbf62bf1d114257a8f43", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.js": "c64871270b224233ea67ff31c3fbc0c2e2eb35635da5e4d5a263b930fb96e6e7", + "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.js": "382acfaf113fbd1ee77c63dba72953d984ea715f2d99748a12b9eae70c081d49", + "packages/artplayer/src/player/thumbnailsMix.js": "43bdbd9b62a803f4966103c6718305a9ef665d25df26f735d3e34558ddf339bf", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.js": "70920c8f785dca6d4bd66d82b996c37f1b69265190d7747ae8de298afae3604e", + "packages/artplayer/src/player/urlMix.ts": "23ee05577af66e3608f9c6d63f060bd3de68a99b1992e4e35e45f16a08a8c14f", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.js": "26f4a21691a2b2f767304b7d2fe40a35c599575651b9ace0c55a709a2be279b8", + "packages/artplayer/src/plugins/builtins.ts": "f4716e8db58a987c682dcd4d329f70a4a38196ee57100255955760cec924070d", + "packages/artplayer/src/plugins/fastForward.js": "d1f396efb22a279f9450fd02f85dc2245d274dbf0d36c99e87a5e5f895cc0029", + "packages/artplayer/src/plugins/index.ts": "28d13abc95cbedafadae0fdb682bf86fda9b705191c51843943a5dadddbd0a53", + "packages/artplayer/src/plugins/lock.js": "843caf8c7981463e8dadf1510cd028e7e70049f5a10038bd66dfccbc63bb7886", + "packages/artplayer/src/plugins/miniProgressBar.js": "3bf48d30c209105a0144c17062d6ea4e2bdd351b1bc928df73ea1680b78462e2", + "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": "2bb29994c60d0c47517bdf7cacb6afac7d65075f0a67d895a3ce52250b668232", + "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": "799e7adeac76c4a327201ec66f10d8f25f92387409f1e5e65f265df7711973e1", + "packages/artplayer/src/setting/update.ts": "3725fd69b369e4a345b1657ab559a915ab967c20088a093e288ffa7370cda264", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/switch.ts": "697ab56a765f957e3ce1da076c69cfc11dbf0901efecae0199cd94c729e0b236", + "packages/artplayer/src/source/types.ts": "9456d3d2f798188b730d99ef015e8a0a145598b0fe3ad1036b84f4a7cc1c5e6d", + "packages/artplayer/src/storage.js": "92067265b7f1104c4680e27e35726cf033811c6551e7c38d66028f2dd5300491", + "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": "ec67999b458d5545a4f17eeda922872823d655da012fa69113902629ad847548", + "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": "c8537df19c1d615419a8396db5846b4de05f61e61df8c0ed89613f0051b81e38", + "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": "743837b3c84fc5fee40120598bd484c10bd4202b371002709c269a700919dda2", + "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": "e56db829d7588f3a5dfafd6e8377f93f0892cfe442710be3740e1136812dd2bd", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "23f67e78ee43f9ad9099c94f28e51c6113b167603ffbbcf2d6ca2b68cc40b803", + "packages/artplayer/src/template.ts": "05c1499adc5dce27addf5761bec58d803f526d9b5b62c367c631e4cf2991391d", + "packages/artplayer/src/utils/compatibility.js": "51290838ef62be8e4251f4db8ecdd45a626cecd8c732e4e53a1c55df8d454a13", + "packages/artplayer/src/utils/component.ts": "d04a66213406ae3223326c2d470363e197dd1540519caa632f9d06378af989cc", + "packages/artplayer/src/utils/dom.js": "a625a0d832f717fbdf186099d1ace1f0dd51f1ea871417ffa856a7186206fb91", + "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" + }, + "artifacts": { + "packages/artplayer/dist/artplayer.js": "9b66f868955e068acfd2c302a743387d7402c5af53c2c6908232d02bd6ca5696", + "packages/artplayer/dist/artplayer.legacy.js": "379d8310d4b5cdf7b0fa4b80b362953e3c490b9ee8688fa005cbc164bd199475", + "packages/artplayer/dist/artplayer.mjs": "be55c7dbd09bb41157f781d280dca7a046930d8bf61b48ceb7efb3f8f70e10fc" + }, + "tests": { + "test/hotkey.test.js": "b647a4552ce43591f532d6295bf6d2034d7c301a2a9dae88cdb1b77e651ad5b5", + "test/types/hotkey.ts": "bc08aa59a8359a86e49cc95f880ae09d5c90a501d4d0ddae7d7467e90b042ef7", + "test/browser/hotkey.spec.js": "984e042d277da6ec092e5a16053bef0f2a144a83868dc30cee82a696c2adfeff", + "test/listener-registry.test.js": "07dcdb1945e530a3928b28a3758d22eca0db70bf4a00dd7e0527a56ef407c133", + "test/browser/listener-registry.spec.js": "54c40eebcd818342e92f875cb639d31d1fa0a0fc95897de2cbfbbd4df793ac94", + "test/global-events.test.js": "ab57213ce56ddf7139c3b045915a6d5c5e6e7aaf84075e656c02a0d8a61b3ffc", + "test/browser/global-events.spec.js": "67ef2bc32419f17bb10ff40f7d9e542c110f2202028e5a17d58780e2cc6cf5f3", + "test/browser/lifecycle.spec.js": "7726535769bdf01a57d15d562bad9b3bb2cce0d979b7b0def6cbcf77bd72f453", + "test/browser/pointer-events.spec.js": "fa789898942d6eeffcb1f8867af46abcdb1dc8a515470ffdb18e89e8fafc4985", + "test/pointer-events.test.js": "8eccc6b72f025183cb93f1bbc2c03e42a98e1a3bdf6c03e8609c1b2fc9c2ea2d", + "package.json": "f964aee310f22b26ad1d3cda4186a9b040b49b9845191689d8fc2b636f183dbc" + }, + "ci": { + "passed": 300, + "unit": 271, + "engineering": 4, + "baseline": 25, + "strictSourceFiles": 176, + "logSha256": "7d5a3b498fd7a21214eacd0bea25a11fae943107cbd67f9ab51b22e5da62ccef" + }, + "browser": { + "scope": "Hotkey, native listeners, global binding, lifecycle and pointer interaction only; workspace source, not final installed UMD/legacy acceptance", + "stats": { + "startTime": "2026-09-11T02:35:14.510Z", + "duration": 40503.72, + "expected": 165, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "candidateSha256": "8c02454d3468f3b9c7e86baa4778aef0d43f3e97dbb4a4a2a012202c5d46b70f", + "cases": [ + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed" + }, + { + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed" + }, + { + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed" + }, + { + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed" + }, + { + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed" + }, + { + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed" + } + ], + "reportSha256": "5ea42fc3e4cf8647a2695a95c0e6dd061f7e5e761767eed1bf07d87a047c9108" + }, + "baselines": [ + { + "file": "core17-listeners-baseline", + "stats": { + "startTime": "2026-09-11T02:01:57.051Z", + "duration": 13748.359, + "expected": 12, + "skipped": 0, + "unexpected": 12, + "flaky": 0 + }, + "reportSha256": "881fece2745d286782d4af78efb80f464b10d37a5aa25225d01b986c7408b1d7" + }, + { + "file": "core17-listeners-null-baseline", + "stats": { + "startTime": "2026-09-11T02:14:09.648Z", + "duration": 6851.293, + "expected": 3, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "8511bca0e86c3d01e8e58e42466ca2fdb5f92756c9d3235ef13f24ff08d52d7c" + }, + { + "file": "core17-global-baseline", + "stats": { + "startTime": "2026-09-11T02:15:57.255Z", + "duration": 9625.694000000001, + "expected": 9, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "reportSha256": "37c86104c804f611cd7cb293c0e8d809ca7af5bb3f73493bce7b3c3b8ed7b7e9" + }, + { + "file": "core17-pointer-corrected-baseline", + "stats": { + "startTime": "2026-09-11T02:26:41.904Z", + "duration": 14571.454, + "expected": 12, + "skipped": 0, + "unexpected": 12, + "flaky": 0 + }, + "reportSha256": "c7acda3fce1759797758b344ef1536a0b79edae02d84a5bc31f180b43f28fcce", + "failures": [ + { + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium" + }, + { + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium" + }, + { + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium" + }, + { + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium" + }, + { + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox" + }, + { + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox" + }, + { + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox" + }, + { + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox" + }, + { + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit" + }, + { + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit" + }, + { + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit" + }, + { + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit" + } + ], + "note": "Six candidate destruction failures reproduce the product defect; six click-pair failures were an incorrect implicit-ctx fixture assumption, fixed with explicit ctx. Earlier non-configurable toggle replacement was also a fixture error." + }, + { + "file": "core17-pointer-final", + "stats": { + "startTime": "2026-09-11T02:32:35.229Z", + "duration": 48286.415, + "expected": 164, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "reportSha256": "cdc3459e3242953af044428f82ad7fd2a87997f063c4af0e33ffaf670261c86e", + "note": "WebKit initial seek was not awaited before ArrowRight. The test now awaits paused/seek completion and checks actual hotkey delivery; this failed run remains preserved and is not counted as passing." + } + ], + "build": { + "logSha256": "d9bbaf6b06bee8d2782862b50b0638371464584aaee2eb4ba3d7477f66dcbef3", + "i18nLogSha256": "21645b3a7821ad17a7d94ff4a5b386ec24cce3ab976e2a8c7a4b9e68f72a9129" + }, + "remaining": [ + "Events facade and gesture migration", + "Resize/view/RAF scheduling and combined lifecycle checks", + "Full final installed UMD/legacy matrices and exact package consumers; CORE-17 remains doing", + "Physical-device certification remains a release gate; native once bookkeeping stays until explicit/owner cleanup" + ] +} diff --git a/refactor/changes/2026-09-11-CORE-17-input.md b/refactor/changes/2026-09-11-CORE-17-input.md new file mode 100644 index 000000000..d19122c22 --- /dev/null +++ b/refactor/changes/2026-09-11-CORE-17-input.md @@ -0,0 +1,88 @@ +# CORE-17 键盘、手势、焦点与全局事件 + +状态:完成。以下阶段记录保留当时的进度;当前交付结论以末尾最终验收为准。 + +先核实公开键盘注册、焦点及跨 document 行为,保留回调 this、参数、顺序、可变 keys 数组和链式返回。后续处理原生监听器注册/释放、全局 document/window 重绑、点击/悬停/移动/触摸,以及 resize/view/RAF 调度归属。 + +源码观察:Hotkey 的输入判断固定读取全局 document.activeElement,重复 init 会重复订阅;Events 的重绑先删除旧监听,失败期间可能保留部分新监听;触摸只处理结束、缺少取消。尚未复现的点不登记为已确认缺陷。BASE-PERF-01 的 pending resize 已在 CORE-04 修正,本任务继续回归,不重复宣称新修复。 + +## 第一批:Hotkey + +hotkey.ts 保留 art/keys 自有字段、init/add/remove 原型方法、keys 的普通对象原型与数组身份、链式返回、回调 this=art 和原同步事件顺序。input/hotkey-defaults.ts 管理稳定的默认回调;keyboard-focus.ts 判断事件 document 与编辑区域;hotkey-types.ts 描述最小泛型宿主。保持回调数组的旧实时遍历语义,注册/删除中途修改数组仍直接影响本次派发;不借本次迁移静默改成快照模型。 + +发布/候选初始基线 24 项中,15 通过、候选目标 9 失败,复现 iframe 与 Shadow DOM 输入被快捷键拦截,以及重复 init 触发两次。迁移后 24 项通过。随后补充已发布包的 prototype-named key 复现:constructor/toString/__proto__ 的注册会因继承属性报错;候选保持普通 keys 原型,用自身属性注册消除碰撞。分别登记 BASE-DOM-16/17 与 BASE-LIFE-23,当前均保持 open,等待完整 CORE-17 安装包出口。 + +键盘判断优先读取实际事件 document,回退到 player 当前 ownerDocument,并检查深层 shadow focus/composed target;input/textarea/select、继承或 plaintext 编辑区、IME 组合输入不触发快捷键,仍保留通用 keydown 通知。修饰键规则保持。实例 scope 清理订阅,销毁中回调不再继续后续回调或 hotkey/keydown 通知;同步回调错误仍保留身份。重复 init 复用默认回调,并可恢复显式移除的默认键;移动端默认不初始化,原手动 init 路径保留。 + +新增 9 项 Node 测试(与已有播放测试合跑 23 项),覆盖公开形态、默认与自定义键、重复初始化/恢复、回调上下文与数组修改、销毁、错误、修饰键/IME 和空 activeElement。类型用例保留泛型扩展与 this,拒绝错误事件/接收者类型。浏览器扩展首轮 45 项通过;最后补入移动 UA 的旧手动 init 行为,并与显示模块组合回归。未新增依赖,test:unit 加入键盘用例。 + +Events 注册/重绑、点击/手势/悬停以及 view/resize/RAF 仍未完成;本阶段不标记整个 CORE-17 完成,也不作完成任务提交。 + +本批最终 CI 278 项(249 单元、4 工程、25 基线)、168 个生产 TS 文件和五组消费者严格检查通过;键盘与显示模式组合 351 项三浏览器通过,含键盘 51 项。核心三个格式和 i18n 构建通过,docs/compiled 一致;独立重建候选并逐项核对浏览器 manifest,见 [键盘阶段证据](../baselines/hotkey-validation.json)。这不是全量源码浏览器或最终安装 UMD/legacy 验收。回退本批时恢复 hotkey.js,删除 input/hotkey 与 keyboard-focus 模块和对应测试,再通过仓库脚本重建;保留基线缺陷记录。 + +## 第二批:原生监听器与全局重绑 + +events/listener-registry.ts 管理原生监听器注册、capture 快照、数组失败回滚、abort 和清理;events/index.js 仍保留旧门面、bound proxy/hover、destroyEvents Set 与初始化顺序。返回的 disposer 直接执行后移除记录,重复执行无副作用。移除失败警告并保留记录供后续 remove/destroy 重试,其他监听器继续清理;自定义 target 永久拒绝移除仍属于明确能力边界。 + +保留原回调交给原生 EventTarget,因此 this、event 身份、外部 removeEventListener、原生 once/重复注册语义保持。once 触发后,记录在显式 disposer 或实例销毁时清除;不为了提前清记录包装用户回调。相同回调的重复注册不做引用计数。abort 清理记录,预先 aborted 的信号不注册。测试还发现本次迁移曾误拒绝 null options:旧包三浏览器通过、初始候选三浏览器失败,已恢复原生默认行为并保留回归用例。 + +原生注册初始基线 24 项中旧包 12 通过、候选目标 12 失败;迁移后配合生命周期 54 项通过。补入 null、once/abort 后,与键盘/生命周期合跑 117 项通过。新增 9 项 Node 测试覆盖原生身份、可变选项、对象监听器、取消、注册后抛错、销毁中注册、清理失败重试、手动 destroy 后复用和重复注册。确认 BASE-LIFE-24,保持 open 等待整个 CORE-17 安装包出口。 + +events/globalInit.ts 与 global-types.ts 拆出全局监听组及最小宿主。先注册完整新组,成功后再切换活动组并释放旧组;失败回滚新组,保留旧组可用。暂存组不转发事件,代次检查确保嵌套重绑由更新调用生效,销毁中断的注册不会晚到激活。保留原事件名称/身份、void 返回、document/window 独立回退规则(单传 document 不隐式更换 window)及成功重绑后不再接收旧目标事件。 + +实际 iframe 的初始基线 12 项中 9 通过、候选失败回滚目标 3 失败,证实旧实现失败后失去旧 document 并保留部分新监听。迁移后与键盘合跑 63 项通过;再补浏览器嵌套重绑/销毁检查。5 项 Node 测试覆盖 ownerDocument 变化、window 注册失败、暂存期间事件、嵌套重绑与销毁。确认 BASE-LIFE-25,保持 open;两组共 14 项 Node 测试通过。未新增依赖,已把两组测试接入 test:unit。 + +以上键盘阶段指纹只对应第一批历史源码,不能代表第二批。第二批最终 CI 292 项(263 单元、4 工程、25 基线)、171 个生产 TS 和五组消费者严格检查通过;键盘/原生监听器/全局重绑/生命周期组合 135 项三浏览器通过,无重试、跳过或页面错误。核心三个格式和 i18n 已重建,docs/compiled 字节一致;独立重建并逐项核对候选 manifest,见 [监听器及重绑阶段证据](../baselines/input-listeners-validation.json)。这是源码阶段的局部组合回归,不是最终安装包全量验收。 + +点击、悬停、移动、手势和 resize/view/RAF 仍待实施。回退本批时恢复 events/index.js/globalInit.js,删除新的 listener-registry/globalInit/global-types TS 与测试,并用仓库脚本重建。整个 CORE-17 仍为 doing,不作完成任务提交。 + +## 第三批:点击、焦点、悬停与移动 + +clickInit.ts、hoverInit.ts、moveInit.ts 迁移为 TS,pointer-types.ts 定义最小宿主/监听接口,pointer-focus.ts 独立管理文档焦点订阅。保留原始 Event、类名变化先于 hover 通知、isInput 仅识别 INPUT 的旧语义、单/双击闭区间阈值、第三次点击重置、动态静态配置与嵌套同步派发。Emitter 的 this 仍由显式 ctx 参数决定,不能套用 hotkey 的 this=art 约定。销毁移除自有焦点订阅,并阻止失效的点击/悬停/移动回调继续修改状态。 + +确认 BASE-LIFE-26:桌面 click 或移动 UA dblclick 回调销毁实例后,旧实现仍调用原生媒体 play。候选在用户事件回调返回后检查实例生命周期,同时在处理入口拦截已关闭实例;单元测试也验证销毁时不再进入 fullscreen 默认动作。该修正不改变正常单击播放、双击行为、用户异常身份及内部播放拒绝处理。 + +最初浏览器夹具错误地替换不可重定义的 toggle 属性,导致 18 项失败;修正为观察底层 video.play 后,暴露出默认 Emitter ctx 的错误测试假设。保留了两次失败报告,不把这些计为产品缺陷;第二次报告中另有 6 项候选销毁目标失败,均复现上述真实问题。最终测试显式传 ctx,保留旧不可配置属性不变。修复后 24 项三浏览器契约通过,再新增实际鼠标点击、播放/暂停、焦点和 hover 的 6 项浏览器验证通过。新增 8 项单元测试通过,包括阈值、嵌套派发、销毁、异常与自有订阅清理,已接入 test:unit,未新增依赖。 + +最终 CI 300 项(271 单元、4 工程、25 基线)、176 个生产 TS 与五组消费者严格检查通过。首次组合浏览器为 164 通过、1 项 WebKit 键盘定位失败;该测试设置初始 currentTime 后未等待定位完成,现补充 paused/seeking 前置条件,并断言方向键确实进入 hotkey。保留失败记录,修正测试后组合 165 项三浏览器通过,无重试/跳过/页面错误,含指针交互 30 项。核心三个格式与 i18n 重建通过,独立重建候选并核对每项 manifest、源码及 docs/compiled 指纹,见 [指针阶段证据](../baselines/pointer-validation.json)。 + +前两批证据仅代表各自历史源码。本批是局部源码组合回归,手势、resize/view/RAF 与 Events 门面还待迁移,整个 CORE-17 安装包出口未完成。回退本批时恢复三个 Init.js,删除 pointer-focus/pointer-types 和对应测试,通过仓库脚本重建。保持 doing,不作完成任务提交。 + +## 第四批:触摸手势 + +gestureInit.ts 负责移动端安装与选项分支;gesture-controller.ts 管理触点、源身份、方向快照和结束/取消/锁定订阅;gesture-direction.ts 保留原两像素阈值与对角边界;gesture-types.ts 描述最小宿主和当前手势。gesture=false 仍支持进度条触摸,isLive 不安装;普通视频拖动保留 TOUCH_MOVE_RATIO,进度条拖动保留全尺寸倍率,旋转时保留纵向计算。 + +初始 36 项三浏览器基线:21 通过、15 个候选修正目标失败。复现 touchcancel、锁定、多指、触点 identifier 改变后继续沿用旧拖动,以及 seek 回调销毁后继续发出 setBar。分别登记 BASE-LIFE-27/28。候选取消失效手势,并在用户回调后检查手势/实例/源身份;进度条触摸也不会在 setBar 回调销毁或启动新手势后继续旧 seek。失败起始回调保留异常身份并取消未完成手势。 + +control/progress/position.ts 改为最小宿主,并增加可选的 active 回调,供触摸调用在 setBar 与 seek 之间检查生命周期;原双参数桌面调用默认行为保持,纳入既有组件回归。新增 document:touchcancel 转发及同名公开 Event 声明,旧事件/类型保持。原生目标也监听取消,因此全局 document 被重绑后仍可释放自身手势。源切换通过既有 source 身份取消,避免依赖延迟到达的媒体事件。 + +12 项单元测试通过,覆盖轴/阈值、绝对/相对顺序、锁定/取消/多指/换指、源/旋转改变、无效尺寸、销毁、重入、错误和订阅清理。类型用例校验 TouchEvent 输入和新增取消事件。首轮手势+重绑浏览器为 52 通过、2 项 WebKit 用例停在触摸执行前的初始定位,最终媒体仍接近 0,未进入手势断言;保留失败记录。准备步骤显式播放/暂停以初始化解码器后,54 项通过;另外独立覆盖首次播放前的 seek 请求契约。扩展进度条绝对定位/销毁和原事件顺序后,手势 54 项三浏览器通过。 + +本批最终 CI 312 项(283 单元、4 工程、25 基线)、180 个生产 TS 与五组消费者严格检查通过;输入/生命周期/组件组合 303 项三浏览器通过,含 54 项手势与 84 项组件回归,无重试/跳过/页面错误。核心三个格式和 i18n 已重建,独立重建候选核对全部浏览器 manifest,源码/产物/文档副本指纹一致;公开声明差异逐字核对,仅增加 document:touchcancel。见 [手势阶段证据](../baselines/gesture-validation.json)。 + +浏览器触摸载荷和 Android UA 是受控输入,使用实际 DOM、媒体及定位;不将其宣称为实体手机触摸、滚动仲裁或系统取消的验收。未新增依赖,单元用例加入 test:unit。剩余调度/Events 门面和整个 CORE-17 安装包出口仍待完成;任务保持 doing。回退本批时恢复 gestureInit.js 与 position.ts,删除新的 gesture 模块和测试,撤销新增取消转发/声明后按仓库脚本重建。 + +## 第五批:调度与 Events 门面 + +resizeInit.ts 保留合并触发、动态 RESIZE_TIME、标准状态 autoSize、宽高比恢复与 notice 清理,并在重入销毁后停止后续写入。方向事件按 owner window 的 addEventListener 能力注册,不再依赖 onchange 已被赋值。viewInit.ts 拥有首发节流的复位定时器和订阅,保留构造时 SCROLL_TIME、动态 SCROLL_GAP、无尾随通知及原同步嵌套时序;viewport.ts 按 container 当前 ownerDocument 计算,但不更改原边界/容差公式。公共 throttle/debounce/isInViewport 不改。 + +updateInit.ts 保留 USE_RAF 开关、首次 playing 时立即通知、暂停不发 raf 和单个待执行帧;实例销毁或 raf 回调内销毁不再安排新帧,显式 destroy 通知仍可取消活跃实例的待执行帧。subscriptions.ts 以明确事件映射管理内部订阅并在实例关闭时移除;scheduling-types.ts 定义最小宿主。 + +events/index.ts 完成门面迁移,types.ts 组合初始化器宿主;保留 destroyEvents/proxy/hover/bindGlobalEvents 自有字段、原型方法、bound proxy/hover、注册返回和初始化顺序。bindGlobalEvents 使用 declare,不在构造开始时生成额外字段。strict 检查暴露的泛型推断问题通过显式事件映射修正,没有用 any 绕过;类型用例验证注册重载、回调 payload 和订阅边界。 + +初始 24 项浏览器基线为 15 通过、9 个候选目标失败。确认方向 onchange=null 时无 resize、销毁残留 scroll 节流定时器、跨 iframe 使用错误 viewport;登记 BASE-LIFE-29/30、BASE-DOM-18。首轮迁移后与生命周期组合 51 通过、3 个 viewport 用例仍失败,检查发现测试 top=150 恰好处于旧 50 像素容差边界;改为 top=250,保留闭区间规则并加入单元边界检查,不把容差规则改掉来迎合测试。补入实际 RAF/播放/销毁后,60 项三浏览器组合通过。9 项新增单元测试通过并接入 test:unit。 + +源码阶段 CI 321 项(292 单元、4 工程、25 基线)、188 个生产 TS 文件与五组消费者严格检查通过。实际 core/chapter tarball 安装后 27 项运行时检查、五组类型零诊断。核心三个格式及 i18n 已重建;最终安装 UMD/legacy 完整浏览器矩阵仍在验收,未将本任务标记完成。此前阶段报告仅记录当时源码,最终结论将以完整安装包指纹为准。 + +## 最终验收 + +- Hotkey、Events 门面及全部输入初始化器已迁移 TS,拆出键盘焦点/默认键、原生监听器、全局监听组、指针焦点、手势控制/方向、可见性和调度宿主。核心 183 个与 chapter 5 个生产 TS 文件严格检查通过;主播放器入口的剩余整合继续由后续任务处理。 +- yarn ci:check:321 项通过(292 单元、4 工程、25 基线)。实际 core/chapter tarball 仓库外安装后 27 项运行时、五组类型零诊断。 +- 最终安装 UMD 和 legacy 各完成 1119 项全量及 24 项补充三浏览器检查,分别对同一安装产物累计验证 1143 项;其中输入专项合计 243 项,既有显示模式 300 项;无重试、跳过或未处理页面错误。保留了早期失败记录与修正原因,未把早期阶段指纹混作最终证据。 +- [最终证据](../baselines/input-validation.json)核对全部当前核心源码与打包快照、核心和 chapter 实际浏览器产物、全部包内文件、三个分发格式与 docs/compiled、22 个语言文件和独立分发许可。 +- 保留公开字段/原型、方法绑定、回调数组和 native listener 身份、Emitter 显式 ctx、普通点击/触摸/调度时序。公开声明仅增加 document:touchcancel,其余内容与父提交逐字核对一致;五组旧/新 TS 消费者仍通过。 +- 实际鼠标/键盘播放、定位、iframe 焦点/可见性和 RAF 已验证。触摸载荷、Android UA、IME、方向事件等包含受控路径;实体 iOS/Android 手势、滚动仲裁、系统取消、旋转和安全区仍交 REL-03/REVIEW-02。 +- 保留原生 once/重复注册语义;once 记录在显式 disposer 或 owner 清理时释放。永久拒绝移除的自定义 target 只能警告并保留可重试记录,不承诺强制恢复外部副作用。 +- 无新增依赖、锁文件或版本修改。六个新增 Node 测试文件已接入 test:unit,并补充类型与浏览器用例;既有公共类型差异仍由 CORE-21 协调。回退时恢复输入入口/初始化器与进度位置辅助函数,删除新增输入模块和用例,撤销新增取消事件,再通过仓库脚本重建,保留基线记录。 + +关闭本任务十一项输入/生命周期差异;BASE-PERF-01 的既有 resize 修复仅作回归验证,不重复计为新修复。控件 Tab 可达性 BASE-DOM-01 继续由 CORE-23 完成,未在本任务关闭。当前 214 项中 53 完成、161 待办,下一项 CORE-18 内置插件和提示模块。本任务独立本地提交,不推送或发布;全生态迁移和发布复盘继续按完整计划推进。 diff --git a/refactor/core-design.md b/refactor/core-design.md index 486ea5a2e..556f80375 100644 --- a/refactor/core-design.md +++ b/refactor/core-design.md @@ -6,7 +6,7 @@ - [入口](../packages/artplayer/src/index.js)顺序构造所有子系统;[player](../packages/artplayer/src/player/index.js)通过 mixin 将属性安装到 art。 - [Component](../packages/artplayer/src/utils/component.ts)负责控件缓存、DOM 和监听器;[Setting](../packages/artplayer/src/setting/index.ts)还有独立的树、渲染和更新语义。 -- [Events](../packages/artplayer/src/events/index.js)集中管理一部分 DOM 监听器,但定时器、异步请求和内部 Emitter 订阅仍由各模块管理。 +- [Events](../packages/artplayer/src/events/index.ts)已迁移为 TS,管理 DOM 监听器和全局重绑;输入调度、内部订阅与异步请求分别通过所属模块接入实例或操作作用域。 - [声明](../packages/artplayer/types/artplayer.d.ts)与源码独立维护;[build-ts](../scripts/build-ts.js)进行文本拼接。 ## 目标职责 diff --git a/refactor/plan.md b/refactor/plan.md index de561b24d..ed9ca0f55 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -4,7 +4,7 @@ 基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。 -状态:todo 162 / doing 0 / blocked 0 / done 52 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 +状态:todo 161 / doing 0 / blocked 0 / done 53 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。 @@ -120,7 +120,7 @@ | CORE-14 | artplayer
拆分设置树、渲染和布局 | CORE-13 | setting model/selection/render/layout 的分批实现 | 不强行统一控件返回值,嵌套选择、默认高亮、更新清理通过;结合 BASE-DOM-02 验证窄容器设置定位;接续 BASE-TYPE-07 的 find null、add/update item、remove undefined 声明冲突 | H | done | | CORE-15 | artplayer
迁移字幕获取、解析和渲染 | CORE-11, CORE-13 | subtitle 请求/track/DOM/URL 生命周期与类型 | 过期结果、偏移、cue 数组、原生全屏及错误路径通过;接续 BASE-TYPE-07 的真实 cue 数组与旧隐式 scalar 回调声明兼容 | H | done | | CORE-16 | artplayer
迁移全屏、PiP、mini 与尺寸模式 | CORE-11, CORE-12 | 显示模式服务和原公开属性门面 | 模式互斥/恢复位置、手势权限、移动方向和退出失败通过 | H | done | -| CORE-17 | artplayer
迁移键盘、手势、焦点和全局事件 | CORE-13, CORE-16 | events/hotkey 的明确 document 与资源归属 | 跨 document 重绑、触摸/键盘、快捷键及销毁无重复响应;修复 BASE-PERF-01 pending resize debounce 销毁后执行,并验证正常 resize 不变 | H | todo | +| CORE-17 | artplayer
迁移键盘、手势、焦点和全局事件 | CORE-13, CORE-16 | events/hotkey 的明确 document 与资源归属 | 跨 document 重绑、触摸/键盘、快捷键及销毁无重复响应;修复 BASE-PERF-01 pending resize debounce 销毁后执行,并验证正常 resize 不变 | H | done | | CORE-18 | artplayer
迁移内置插件和提示模块 | CORE-14, CORE-16, CORE-17 | autoPlayback/autoOrientation/fastForward/lock/miniProgressBar 及 info/notice/loading/mask | 默认启用条件、storage 格式、定时器/动画清理通过;结合 BASE-PERF-01 防止销毁后重新安排 notice timer;接续 BASE-TYPE-07 的 notice.show boolean getter 与历史读类型冲突 | M | todo | | CORE-19 | artplayer
整理进度、质量、缩略图和截图 | CORE-10, CORE-13, CORE-16 | 相关 player/control 功能与纯计算分离 | 截图跨域失败、缩略图布局、quality/进度边界保持 | M | todo | | CORE-20 | artplayer
收敛核心入口与依赖方向 | CORE-14, CORE-15, CORE-18, CORE-19 | Artplayer 门面、初始化依赖与最终目录 | 所有核心自有源码迁移,公开描述符/静态接口/事件差分通过 | H | todo | @@ -451,6 +451,7 @@ - CORE-14: [记录](changes/2026-09-11-CORE-14-setting.md) [记录](baselines/setting-validation.json) - CORE-15: [记录](changes/2026-09-11-CORE-15-subtitle.md) [记录](baselines/subtitle-validation.json) - CORE-16: [记录](changes/2026-09-11-CORE-16-display.md) [记录](baselines/display-validation.json) +- CORE-17: [记录](changes/2026-09-11-CORE-17-input.md) [记录](baselines/input-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 f2298bd72..1f0beac87 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,13 @@ # 进度与证据 +## 当前实施:CORE-17 输入、全局事件与调度完成 + +Hotkey 与 Events 全部初始化器已迁移 TS,拆清焦点、监听器、全局重绑、手势和调度;正常旧 API、回调/事件和交互保持,新增 document:touchcancel。 + +CI 321 项、核心 183 个与 chapter 5 个生产 TS 文件严格检查通过。实际安装 UMD 与 legacy 各通过 1119 项全量和 24 项补充三浏览器检查,对同一产物累计 1143 项,各含 243 项输入专项;真实 tarball 27 项运行时及五组类型零诊断,源码、包内文件、产物、文档副本、语言与许可指纹一致。见 [交付](changes/2026-09-11-CORE-17-input.md) 和 [最终证据](baselines/input-validation.json)。 + +关闭十一项输入/生命周期差异;控件 Tab 可达性 BASE-DOM-01 留 CORE-23;物理触摸/IME/方向等限制仍由 REL-03/REVIEW-02 验收。当前 214 项:53 完成、161 待办;下一项 CORE-18 内置插件和提示模块。本任务独立本地提交,不推送或发布。 + ## 当前实施:CORE-16 显示模式完成 全屏、video-only fallback、PiP、mini、自动尺寸、宽高比、翻转和方向已迁移 TS,拆清能力、状态、几何、DOM 和资源归属。修复重入/取消/销毁、节点和样式恢复、跨实例归属、过期事件及无效尺寸;正常旧 API、返回和事件保持。 diff --git a/refactor/risk-table.md b/refactor/risk-table.md index 1b6a3fe37..56cc76434 100644 --- a/refactor/risk-table.md +++ b/refactor/risk-table.md @@ -84,3 +84,14 @@ | BASE-DOM-14 | resolved / 已复现 | Unready media sizing partially overwrites layout and emits NaN height | CORE-16 | | BASE-DOM-15 | resolved / 已复现 | Auto orientation exit clears caller-owned inline dimensions and transforms | CORE-16 | | BASE-LIFE-22 | resolved / 已复现 | Orientation lock success after fullscreen exit reactivates a cancelled player | CORE-16 | +| BASE-DOM-16 | resolved / 已复现 | Hotkeys intercept input in rebound documents and shadow roots | CORE-17 | +| BASE-DOM-17 | resolved / 已复现 | Prototype-named hotkeys fail registration through inherited keys properties | CORE-17 | +| BASE-LIFE-23 | resolved / 已复现 | Repeated Hotkey initialization accumulates keyboard subscriptions | CORE-17 | +| BASE-LIFE-24 | resolved / 已复现 | Mutable capture options and partial native registration failures leave listeners behind | CORE-17 | +| BASE-LIFE-25 | resolved / 已复现 | Failed global rebinding drops the old document and retains partial new listeners | CORE-17 | +| BASE-LIFE-26 | resolved / 已复现 | Click callbacks that destroy the player still trigger subsequent default playback actions | CORE-17 | +| BASE-LIFE-27 | resolved / 已复现 | Cancelled, locked or replaced touches continue a previous seek gesture | CORE-17 | +| BASE-LIFE-28 | resolved / 已复现 | Gesture callbacks continue seeking or updating progress after destruction | CORE-17 | +| BASE-LIFE-29 | resolved / 已复现 | Scroll throttle reset timers remain pending after player destruction | CORE-17 | +| BASE-LIFE-30 | resolved / 已复现 | Screen orientation changes are ignored when onchange is initially null | CORE-17 | +| BASE-DOM-18 | resolved / 已复现 | View visibility uses the original global viewport after container adoption into an iframe | CORE-17 | diff --git a/refactor/risks.json b/refactor/risks.json index fd16196a2..253d6a44f 100644 --- a/refactor/risks.json +++ b/refactor/risks.json @@ -1653,6 +1653,231 @@ "test/display-orientation.test.js" ], "resolutionRationale": "Owned timers and subscriptions cancel cleanly; orientation request tokens prevent stale classes/notices and old-instance unlock of newer ArtPlayer locks. Final installed UMD/legacy each pass 900 browser cases and exact-package consumers pass. Controlled platform paths do not certify physical devices; REL-03/REVIEW-02 retains that release gate." + }, + { + "id": "BASE-DOM-16", + "title": "Hotkeys intercept input in rebound documents and shadow roots", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/hotkey.spec.js", + "refactor/changes/2026-09-11-CORE-17-input.md" + ], + "compatibleResolution": "Resolve the keyboard event document and deep editable focus while retaining normal shortcuts, modifiers and generic keydown notifications.", + "closureCriteria": "Final installed matrices cover real typing and playback keys, iframe/global rebinding, shadow and inherited editing, composition and source ownership.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Event-document and deep editable focus checks preserve actual iframe/shadow typing while retaining ordinary shortcuts. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-DOM-17", + "title": "Prototype-named hotkeys fail registration through inherited keys properties", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/hotkey.spec.js", + "test/hotkey.test.js" + ], + "compatibleResolution": "Use own-property registration without changing the public keys object prototype, callback arrays, chainable methods or receiver contract.", + "closureCriteria": "Installed and unit regressions retain normal registration/removal, prototype-name safety, array identity, callback mutation and original errors.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Own-property registration supports prototype-named keys without changing the public keys prototype or arrays. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-LIFE-23", + "title": "Repeated Hotkey initialization accumulates keyboard subscriptions", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/hotkey.spec.js", + "test/hotkey.test.js" + ], + "compatibleResolution": "Own one subscription in the instance scope and reuse default callbacks, preserving explicit default restoration and stopping post-destroy dispatch.", + "closureCriteria": "Final installed matrices cover repeated init, default restoration, mobile manual initialization, real key operations and destruction during a callback.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "One scoped hotkey subscription and stable default callbacks retain opt-in initialization and restoration. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-LIFE-24", + "title": "Mutable capture options and partial native registration failures leave listeners behind", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/listener-registry.spec.js", + "test/listener-registry.test.js", + "refactor/changes/2026-09-11-CORE-17-input.md" + ], + "compatibleResolution": "Snapshot capture, roll back failed registration, release direct-disposer and aborted records, and preserve native callback identity, once and duplicate semantics.", + "closureCriteria": "Final installed matrices cover mutable/null options, registration failure, direct native removal, once/abort, retryable cleanup and destruction during registration.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Capture snapshots, rollback and owned disposal retain native callback identity and handle abort/failure/destruction. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-LIFE-25", + "title": "Failed global rebinding drops the old document and retains partial new listeners", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/global-events.spec.js", + "test/global-events.test.js", + "refactor/changes/2026-09-11-CORE-17-input.md" + ], + "compatibleResolution": "Commit a new document/window binding only after registration succeeds, keep the previous binding on failure and cancel interrupted generations without changing event identities or target fallback rules.", + "closureCriteria": "Final installed matrices cover actual iframe rebinding, document/window failure rollback, nested rebinding, destruction and keyboard focus integration.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Staged global bindings commit only on successful registration; cancelled/reentrant generations cannot overwrite newer targets. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-LIFE-26", + "title": "Click callbacks that destroy the player still trigger subsequent default playback actions", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/pointer-events.spec.js", + "test/pointer-events.test.js", + "refactor/changes/2026-09-11-CORE-17-input.md" + ], + "compatibleResolution": "Check instance closure before pointer handling and after click/double-click callbacks, own document focus subscriptions, and retain native events, click thresholds, nested dispatch and normal default actions.", + "closureCriteria": "Final installed matrices cover real mouse playback, desktop/mobile callback destruction, normal click pairs, focus/hover/move behavior and unit fullscreen/error/cleanup contracts.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Pointer handlers check closure after user callbacks and no longer trigger playback/fullscreen after destruction. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-LIFE-27", + "title": "Cancelled, locked or replaced touches continue a previous seek gesture", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/gesture.spec.js", + "test/gesture.test.js", + "refactor/changes/2026-09-11-CORE-17-input.md" + ], + "compatibleResolution": "Track the active touch, source and orientation; cancel invalidated sessions, own touch-end/cancel subscriptions and preserve ordinary drag axes, thresholds and multipliers.", + "closureCriteria": "Final installed matrices retain normal video/progress touch behavior and verify cancel, lock, multitouch, identity changes, source/rotation changes and invalid geometry; physical touch remains a release gate.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Touch/source/orientation identity and cancellation prevent invalid sessions from continuing; normal axes and multipliers remain. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-LIFE-28", + "title": "Gesture callbacks continue seeking or updating progress after destruction", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/gesture.spec.js", + "test/gesture.test.js", + "refactor/changes/2026-09-11-CORE-17-input.md" + ], + "compatibleResolution": "Check the current gesture after progress/seek callbacks and before subsequent writes; permit the shared position helper to check an optional caller lifetime without changing its ordinary call contract.", + "closureCriteria": "Final installed matrices and unit tests cover destruction/reentry/errors during absolute and relative seeking, with original event order and normal desktop progress behavior retained.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Gesture lifetime checks stop post-callback seek/bar/notice writes and preserve nested gesture ownership. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-LIFE-29", + "title": "Scroll throttle reset timers remain pending after player destruction", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/event-scheduling.spec.js", + "test/event-scheduling.test.js" + ], + "compatibleResolution": "Own the view throttle timer and emitter subscriptions while retaining leading-only dispatch, captured delay, live gap and synchronous nested behavior.", + "closureCriteria": "Final installed matrices and unit tests cover pending timer removal, view callback destruction/errors, normal scroll/mini behavior and remaining scheduling ownership.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Owned leading-throttle timers and subscriptions cancel at destruction with normal timing and synchronous errors retained. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-LIFE-30", + "title": "Screen orientation changes are ignored when onchange is initially null", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/event-scheduling.spec.js", + "test/event-scheduling.test.js" + ], + "compatibleResolution": "Detect addEventListener on the owner's orientation target and retain the existing coalesced resize flow and disposal.", + "closureCriteria": "Installed matrices cover controlled orientation events with a null onchange property and resize/cleanup regressions; physical orientation remains a release gate.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "Orientation listeners use event capability on the owner target rather than requiring an assigned onchange handler. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." + }, + { + "id": "BASE-DOM-18", + "title": "View visibility uses the original global viewport after container adoption into an iframe", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-17" + ], + "evidence": [ + "test/browser/event-scheduling.spec.js", + "test/event-scheduling.test.js" + ], + "compatibleResolution": "Use the current container owner document's viewport while preserving the original edge and gap arithmetic.", + "closureCriteria": "Installed matrices cover actual iframe adoption/rebinding, normal visibility and exact gap boundaries without changing public viewport utilities.", + "resolutionEvidence": [ + "refactor/changes/2026-09-11-CORE-17-input.md", + "refactor/baselines/input-validation.json" + ], + "resolutionRationale": "View calculations use the current owner viewport after iframe adoption and preserve the original edge/gap boundaries. Final installed UMD/legacy each pass 1119 full-suite plus 24 supplemental cases on identical artifacts, and exact-package consumers pass. Controlled touch/IME/orientation paths do not waive physical-device release gates." } ] } diff --git a/refactor/tasks.json b/refactor/tasks.json index f52d277bb..d00a8f530 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -1069,11 +1069,14 @@ "CORE-13", "CORE-16" ], - "status": "todo", + "status": "done", "risk": "H", "deliverable": "events/hotkey 的明确 document 与资源归属", "acceptance": "跨 document 重绑、触摸/键盘、快捷键及销毁无重复响应;修复 BASE-PERF-01 pending resize debounce 销毁后执行,并验证正常 resize 不变", - "evidence": [] + "evidence": [ + "changes/2026-09-11-CORE-17-input.md", + "baselines/input-validation.json" + ] }, { "id": "CORE-18", diff --git a/test/browser/event-scheduling.spec.js b/test/browser/event-scheduling.spec.js new file mode 100644 index 000000000..e4d5ed27c --- /dev/null +++ b/test/browser/event-scheduling.spec.js @@ -0,0 +1,125 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core, raf = false) { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate((raf) => { + window.Artplayer.SCROLL_TIME = 24731 + window.Artplayer.RESIZE_TIME = 0 + window.Artplayer.USE_RAF = raf + const orientation = new EventTarget() + orientation.onchange = null + Object.defineProperty(window.screen, 'orientation', { configurable: true, value: orientation }) + window.createPlayer('/test/pattern.mp4') + }, raf) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +for (const core of ['published', 'candidate']) { + test(`${core}: actual animation frames follow playback and stop after destruction inside raf`, async ({ page }) => { + await setup(page, core, true) + await page.evaluate(() => { + window.frameCount = 0 + window.art.on('raf', () => window.frameCount++) + return window.art.play() + }) + await expect.poll(() => page.evaluate(() => window.frameCount)).toBeGreaterThan(2) + await page.evaluate(() => window.art.pause()) + const paused = await page.evaluate(() => window.frameCount) + await page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)))) + expect(await page.evaluate(() => window.frameCount)).toBe(paused) + await page.evaluate(() => { + window.art.once('raf', () => window.art.destroy()) + return window.art.play() + }) + await expect.poll(() => page.evaluate(() => window.art.isDestroy)).toBe(true) + const destroyed = await page.evaluate(() => window.frameCount) + await page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)))) + expect(await page.evaluate(() => window.frameCount)).toBe(destroyed) + }) + + test(`${core}: Events keeps its public fields, prototype and detached native methods`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const events = art.events + const target = document.createElement('div') + let hits = 0 + const { proxy, hover } = events + const dispose = proxy(target, 'example', () => hits++) + hover(target, () => hits++, () => hits++) + target.dispatchEvent(new Event('example')) + target.dispatchEvent(new Event('mouseenter')) + target.dispatchEvent(new Event('mouseleave')) + events.remove(dispose) + target.dispatchEvent(new Event('example')) + const result = { fields: Object.keys(events).sort(), prototype: Object.getOwnPropertyNames(Object.getPrototypeOf(events)).sort(), hits } + art.destroy() + return result + })).toEqual({ fields: ['bindGlobalEvents', 'destroyEvents', 'hover', 'proxy'], prototype: ['constructor', 'destroy', 'hover', 'proxy', 'remove'], hits: 3 }) + }) + + test(`${core}: screen orientation dispatch works when onchange has no assigned handler`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(async () => { + const art = window.art + let resized = 0 + art.on('resize', () => resized++) + window.screen.orientation.dispatchEvent(new Event('change')) + await new Promise(resolve => setTimeout(resolve, 30)) + art.destroy() + return resized + })).toBe(core === 'candidate' ? 1 : 0) + }) + + test(`${core}: destruction releases the scroll throttle reset timer`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const set = window.setTimeout + const clear = window.clearTimeout + const pending = new Set() + window.setTimeout = function (callback, delay, ...args) { + const timer = set.call(this, callback, delay, ...args) + if (delay === 24731) + pending.add(timer) + return timer + } + window.clearTimeout = function (timer) { + pending.delete(timer) + return clear.call(this, timer) + } + try { + art.emit('window:scroll', new Event('scroll')) + const before = pending.size + art.destroy() + return { before, after: pending.size } + } + finally { + for (const timer of pending) + clear.call(window, timer) + window.setTimeout = set + window.clearTimeout = clear + } + })).toEqual({ before: 1, after: core === 'candidate' ? 0 : 1 }) + }) + + test(`${core}: view visibility uses the container's current iframe viewport`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const frame = document.createElement('iframe') + frame.style.cssText = 'width:200px;height:100px' + document.body.append(frame) + const container = art.template.$container + container.style.cssText = 'position:absolute;top:250px;left:0;width:200px;height:100px' + frame.contentDocument.body.append(container) + art.events.bindGlobalEvents() + const seen = [] + art.on('view', visible => seen.push(visible)) + frame.contentWindow.dispatchEvent(new Event('scroll')) + art.destroy() + frame.remove() + return seen + })).toEqual([core === 'published']) + }) +} diff --git a/test/browser/gesture.spec.js b/test/browser/gesture.spec.js new file mode 100644 index 000000000..25d69de6f --- /dev/null +++ b/test/browser/gesture.spec.js @@ -0,0 +1,150 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core, primeMedia = true) { + await page.addInitScript(() => Object.defineProperty(navigator, 'userAgent', { configurable: true, value: 'ArtPlayer Android gesture fixture' })) + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(() => { + window.events = [] + window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, gesture: true }) + window.touch = (target, type, points) => { + const event = new Event(type, { bubbles: true, cancelable: true }) + Object.defineProperty(event, 'touches', { value: points.map(([pageX, pageY, identifier = 1]) => ({ pageX, pageY, clientX: pageX, clientY: pageY, identifier })) }) + target.dispatchEvent(event) + return event + } + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + if (!primeMedia) + return + await page.evaluate(() => window.art.play()) + await expect.poll(() => page.evaluate(() => window.art.currentTime > 0.1)).toBe(true) + await page.evaluate(() => window.art.pause()) + await expect.poll(() => page.evaluate(() => window.art.template.$video.paused && !window.art.template.$video.seeking)).toBe(true) + await page.evaluate(() => { + window.art.currentTime = 2 + }) + await expect.poll(() => page.evaluate(() => !window.art.template.$video.seeking && Math.abs(window.art.currentTime - 2) < 0.1)).toBe(true) +} + +for (const core of ['published', 'candidate']) { + test(`${core}: a gesture before first play still issues the requested seek`, async ({ page }) => { + await setup(page, core, false) + expect(await page.evaluate(() => { + const art = window.art + const start = art.currentTime + const expected = start + art.duration * 0.1 * art.constructor.TOUCH_MOVE_RATIO + const requests = [] + art.on('seek', (time, requested) => requests.push(requested)) + window.touch(art.template.$video, 'touchstart', [[100, 100]]) + window.touch(art.template.$video, 'touchmove', [[100 + art.width * 0.1, 100]]) + art.destroy() + return { count: requests.length, valid: Math.abs(requests[0] - expected) < 0.000001 } + })).toEqual({ count: 1, valid: true }) + }) + + test(`${core}: progress touch keeps absolute position and bar-before-seek ordering`, async ({ page }) => { + await setup(page, core) + const result = await page.evaluate(() => { + const art = window.art + const progress = art.template.$progress + const rect = progress.getBoundingClientRect() + const calls = [] + art.on('setBar', (kind, value, event) => { + if (event?.type === 'touchstart') + calls.push(['bar', value, event]) + }) + art.on('seek', (time, requested) => calls.push(['seek', requested])) + const event = window.touch(progress, 'touchstart', [[rect.left + progress.clientWidth / 2, rect.top]]) + window.touch(document, 'touchend', []) + return { order: calls.map(item => item[0]), percentage: calls[0][1], identity: calls[0][2] === event, requested: calls[1][1], expected: art.duration / 2 } + }) + expect(result.order).toEqual(['bar', 'seek']) + expect(result.percentage).toBeCloseTo(0.5, 6) + expect(result.identity).toBe(true) + expect(result.requested).toBeCloseTo(result.expected, 6) + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeCloseTo(result.expected, 1) + await page.evaluate(() => window.art.destroy()) + }) + + test(`${core}: destroy during absolute progress touch stops the following seek`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const progress = art.template.$progress + const rect = progress.getBoundingClientRect() + let seeks = 0 + art.on('seek', () => seeks++) + art.on('setBar', (kind, value, event) => { + if (event?.type === 'touchstart') + art.destroy() + }) + window.touch(progress, 'touchstart', [[rect.left + progress.clientWidth / 2, rect.top]]) + return { seeks, destroyed: art.isDestroy } + })).toEqual({ seeks: core === 'candidate' ? 0 : 1, destroyed: true }) + }) + + test(`${core}: normal touch drag keeps seek/bar ordering and original touch identity`, async ({ page }) => { + await setup(page, core) + const result = await page.evaluate(() => { + const art = window.art + const video = art.template.$video + const calls = [] + const start = art.currentTime + const expected = start + art.duration * 0.2 * art.constructor.TOUCH_MOVE_RATIO + art.on('seek', (time, requested) => calls.push(['seek', requested])) + art.on('setBar', (kind, percentage, event) => { + if (event?.type === 'touchmove') + calls.push(['bar', kind, percentage, event]) + }) + window.touch(video, 'touchstart', [[100, 100]]) + const event = window.touch(video, 'touchmove', [[100 + art.width * 0.2, 100]]) + window.touch(document, 'touchend', []) + return { expected, order: calls.map(item => item[0]), requested: calls[0][1], percentage: calls[1][2], identity: calls[1][3] === event } + }) + expect(result.order).toEqual(['seek', 'bar']) + expect(result.identity).toBe(true) + expect(result.requested).toBeCloseTo(result.expected, 6) + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeCloseTo(result.expected, 1) + await page.evaluate(() => window.art.destroy()) + }) + + for (const cause of ['cancel', 'lock', 'multitouch', 'identifier']) { + test(`${core}: ${cause} invalidates an in-progress gesture`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate((cause) => { + const art = window.art + const video = art.template.$video + const seeks = [] + art.on('seek', (time, requested) => seeks.push(requested)) + window.touch(video, 'touchstart', [[100, 100]]) + window.touch(video, 'touchmove', [[100 + art.width * 0.1, 100]]) + if (cause === 'cancel') + window.touch(video, 'touchcancel', []) + if (cause === 'lock') + art.isLock = true + if (cause === 'multitouch') + window.touch(video, 'touchmove', [[150, 100], [200, 100, 2]]) + window.touch(video, 'touchmove', [[100 + art.width * 0.3, 100, cause === 'identifier' ? 2 : 1]]) + art.destroy() + return seeks.length + }, cause)).toBe(core === 'candidate' ? 1 : 2) + }) + } + + test(`${core}: destroy from a touch seek callback prevents the later progress notification`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const video = art.template.$video + let bars = 0 + art.on('seek', () => art.destroy()) + art.on('setBar', (kind, value, event) => { + if (event?.type === 'touchmove') + bars++ + }) + window.touch(video, 'touchstart', [[100, 100]]) + window.touch(video, 'touchmove', [[100 + art.width * 0.1, 100]]) + return { bars, destroyed: art.isDestroy } + })).toEqual({ bars: core === 'candidate' ? 0 : 1, destroyed: true }) + }) +} diff --git a/test/browser/global-events.spec.js b/test/browser/global-events.spec.js new file mode 100644 index 000000000..15e7c50aa --- /dev/null +++ b/test/browser/global-events.spec.js @@ -0,0 +1,99 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core) { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(() => window.createPlayer('/test/pattern.mp4')) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +for (const action of ['rebind', 'destroy']) { + test(`candidate: ${action} during native global registration cancels the interrupted binding`, async ({ page }) => { + await setup(page, 'candidate') + expect(await page.evaluate((action) => { + const art = window.art + const frames = [document.createElement('iframe'), document.createElement('iframe')] + frames.forEach(frame => document.body.append(frame)) + const [interrupted, newest] = frames + const target = interrupted.contentDocument + const original = target.addEventListener + target.addEventListener = function (name, ...args) { + if (name === 'click') { + if (action === 'destroy') + art.destroy() + else + art.events.bindGlobalEvents({ document: newest.contentDocument, window: newest.contentWindow }) + } + return original.call(this, name, ...args) + } + const received = [] + art.on('document:mouseup', event => received.push(event.target === newest.contentDocument ? 'newest' : 'stale')) + art.events.bindGlobalEvents({ document: target, window: interrupted.contentWindow }) + document.dispatchEvent(new Event('mouseup')) + for (const frame of frames) + frame.contentDocument.dispatchEvent(new frame.contentWindow.Event('mouseup')) + if (!art.isDestroy) + art.destroy() + target.addEventListener = original + for (const frame of frames) + frame.remove() + return { received, remaining: art.events.destroyEvents.size } + }, action)).toEqual({ received: action === 'rebind' ? ['newest'] : [], remaining: 0 }) + }) +} + +for (const core of ['published', 'candidate']) { + test(`${core}: global rebinding forwards original events once and releases the previous document`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const frame = document.createElement('iframe') + document.body.append(frame) + const next = frame.contentDocument + const events = [] + art.on('document:mouseup', event => events.push(event)) + const first = new Event('mouseup') + document.dispatchEvent(first) + const returned = art.events.bindGlobalEvents({ document: next, window: frame.contentWindow }) + art.events.bindGlobalEvents({ document: next, window: frame.contentWindow }) + document.dispatchEvent(new Event('mouseup')) + const second = new frame.contentWindow.Event('mouseup') + next.dispatchEvent(second) + art.destroy() + next.dispatchEvent(new frame.contentWindow.Event('mouseup')) + frame.remove() + return { count: events.length, identity: events[0] === first && events[1] === second, returned: typeof returned } + })).toEqual({ count: 2, identity: true, returned: 'undefined' }) + }) + + test(`${core}: failed global rebinding keeps the previous document and removes partial new listeners`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const frame = document.createElement('iframe') + document.body.append(frame) + const next = frame.contentDocument + const original = next.addEventListener + const failure = new Error('document listener denied') + next.addEventListener = function (name, ...args) { + if (name === 'keydown') + throw failure + return original.call(this, name, ...args) + } + const received = [] + art.on('document:mouseup', event => received.push(event.target === document ? 'old' : 'new')) + let sameError = false + try { + art.events.bindGlobalEvents({ document: next, window: frame.contentWindow }) + } + catch (error) { + sameError = error === failure + } + next.addEventListener = original + document.dispatchEvent(new Event('mouseup')) + next.dispatchEvent(new frame.contentWindow.Event('mouseup')) + art.destroy() + frame.remove() + return { received, sameError } + })).toEqual({ received: core === 'candidate' ? ['old'] : ['new'], sameError: true }) + }) +} diff --git a/test/browser/hotkey.spec.js b/test/browser/hotkey.spec.js new file mode 100644 index 000000000..0141a3a2e --- /dev/null +++ b/test/browser/hotkey.spec.js @@ -0,0 +1,214 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core) { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(() => window.createPlayer('/test/pattern.mp4')) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +for (const core of ['published', 'candidate']) { + test(`${core}: mobile keeps keyboard initialization opt-in through the existing init method`, async ({ page }) => { + await page.addInitScript(() => Object.defineProperty(navigator, 'userAgent', { configurable: true, value: 'ArtPlayer Android keyboard fixture' })) + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const initial = Object.keys(art.hotkey.keys) + let hits = 0 + art.hotkey.add('KeyK', () => hits++) + art.isFocus = true + document.dispatchEvent(new KeyboardEvent('keydown', { code: 'KeyK' })) + const before = hits + art.hotkey.init() + document.dispatchEvent(new KeyboardEvent('keydown', { code: 'KeyK' })) + const result = { initial, before, after: hits } + art.destroy() + return result + })).toEqual({ initial: [], before: 0, after: 1 }) + }) + + test(`${core}: prototype-named hotkeys do not crash or replace the keys prototype`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const prototype = Object.getPrototypeOf(art.hotkey.keys) + const errors = [] + let hits = 0 + art.isFocus = true + for (const key of ['__proto__', 'constructor', 'toString']) { + try { + const callback = () => hits++ + art.hotkey.add(key, callback) + document.dispatchEvent(new KeyboardEvent('keydown', { code: key, cancelable: true })) + art.hotkey.remove(key, callback) + } + catch { + errors.push(key) + } + } + const stable = Object.getPrototypeOf(art.hotkey.keys) === prototype + art.destroy() + return { errors, hits, stable } + })).toEqual({ errors: core === 'candidate' ? [] : ['__proto__', 'constructor', 'toString'], hits: core === 'candidate' ? 3 : 0, stable: true }) + }) +} + +test('candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior', async ({ page }) => { + await setup(page, 'candidate') + await page.evaluate(() => { + window.art.isFocus = true + window.nativeHotkeys = [] + window.art.on('hotkey', event => window.nativeHotkeys.push(event.code)) + }) + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => window.art.playing && window.art.currentTime > 0.1)).toBe(true) + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => window.art.template.$video.paused && !window.art.template.$video.seeking)).toBe(true) + await page.evaluate(() => { + window.art.currentTime = 1 + }) + await expect.poll(() => page.evaluate(() => !window.art.template.$video.seeking && Math.abs(window.art.currentTime - 1) < 0.1)).toBe(true) + await page.keyboard.press('ArrowRight') + expect(await page.evaluate(() => window.nativeHotkeys.at(-1))).toBe('ArrowRight') + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(5) + await expect.poll(() => page.evaluate(() => window.art.template.$video.seeking)).toBe(false) + await page.keyboard.press('ArrowLeft') + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeLessThan(2) + const volume = await page.evaluate(() => { + window.art.volume = 0.5 + return window.art.volume + }) + await page.keyboard.press('ArrowUp') + expect(await page.evaluate(() => window.art.volume)).toBeGreaterThan(volume) + await page.evaluate(() => { + window.art.fullscreenWeb = true + }) + await page.keyboard.press('Escape') + expect(await page.evaluate(() => window.art.fullscreenWeb)).toBe(false) + await page.evaluate(() => window.art.destroy()) +}) + +for (const kind of ['inherited', 'plaintext', 'select']) { + test(`candidate: ${kind} editing and IME composition do not activate player shortcuts`, async ({ page }) => { + await setup(page, 'candidate') + expect(await page.evaluate((kind) => { + const art = window.art + const root = document.createElement('div') + root.innerHTML = kind === 'select' ? '' : `
edit
` + art.template.$player.append(root) + const target = root.querySelector('span,select') + target.focus() + art.isFocus = true + let hits = 0 + const generic = [] + art.hotkey.add('KeyK', () => hits++) + art.on('keydown', value => generic.push(value.code)) + const key = new KeyboardEvent('keydown', { code: 'KeyK', cancelable: true, bubbles: true }) + target.dispatchEvent(key) + target.blur() + const composition = new KeyboardEvent('keydown', { code: 'KeyK', cancelable: true, bubbles: true, isComposing: true }) + document.dispatchEvent(composition) + art.destroy() + return { hits, generic, prevented: [key.defaultPrevented, composition.defaultPrevented] } + }, kind)).toEqual({ hits: 0, generic: ['KeyK', 'KeyK'], prevented: [false, false] }) + }) +} + +test('candidate: destroying during a key callback stops remaining keys and notifications', async ({ page }) => { + await setup(page, 'candidate') + expect(await page.evaluate(() => { + const art = window.art + const calls = [] + art.isFocus = true + art.hotkey.add('KeyK', () => { + calls.push('first') + art.destroy(false) + }) + art.hotkey.add('KeyK', () => calls.push('second')) + art.on('hotkey', () => calls.push('hotkey')) + art.on('keydown', () => calls.push('keydown')) + document.dispatchEvent(new KeyboardEvent('keydown', { code: 'KeyK' })) + art.hotkey.init() + art.emit('document:keydown', new KeyboardEvent('keydown', { code: 'KeyK' })) + return calls + })).toEqual(['first']) +}) + +for (const core of ['published', 'candidate']) { + test(`${core}: hotkey registration retains chain, array identity, receiver and event order`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + art.isFocus = true + const calls = [] + const event = new KeyboardEvent('keydown', { code: 'KeyK', bubbles: true, cancelable: true }) + function callback(value) { + calls.push(['callback', this === art, value === event]) + } + const add = art.hotkey.add('KeyK', callback) + const list = art.hotkey.keys.KeyK + art.hotkey.add('KeyK', callback) + art.on('hotkey', value => calls.push(['hotkey', value === event])) + art.on('keydown', value => calls.push(['keydown', value === event])) + document.dispatchEvent(event) + const count = list.length + const remove = art.hotkey.remove('KeyK', callback) + const result = { chain: add === art.hotkey && remove === art.hotkey, count, retainedArray: list.length === 0, missing: !Object.hasOwn(art.hotkey.keys, 'KeyK'), keysPrototype: Object.getPrototypeOf(art.hotkey.keys) === Object.prototype, prevented: event.defaultPrevented, calls } + art.destroy() + return result + })).toEqual({ chain: true, count: 1, retainedArray: true, missing: true, keysPrototype: true, prevented: true, calls: [['callback', true, true], ['hotkey', true], ['keydown', true]] }) + }) + + test(`${core}: rebound document input retains typing instead of triggering a hotkey`, async ({ page }) => { + await setup(page, core) + await page.evaluate(() => { + const frame = document.createElement('iframe') + frame.id = 'keyboard-frame' + document.body.append(frame) + const doc = frame.contentDocument + doc.body.innerHTML = '' + window.art.events.bindGlobalEvents({ document: doc, window: frame.contentWindow }) + window.hits = 0 + window.art.hotkey.add('KeyK', () => window.hits++) + window.art.isFocus = true + }) + const editor = page.frameLocator('#keyboard-frame').locator('#editor') + await editor.focus() + await editor.press('k') + expect(await page.evaluate(() => window.hits)).toBe(core === 'candidate' ? 0 : 1) + await expect(editor).toHaveValue(core === 'candidate' ? 'k' : '') + await page.evaluate(() => window.art.destroy()) + }) + + test(`${core}: shadow-root input retains typing instead of triggering a hotkey`, async ({ page }) => { + await setup(page, core) + await page.evaluate(() => { + const host = document.createElement('div') + host.id = 'shadow-editor' + window.art.template.$player.append(host) + host.attachShadow({ mode: 'open' }).innerHTML = '' + window.hits = 0 + window.art.hotkey.add('KeyK', () => window.hits++) + window.art.isFocus = true + }) + const editor = page.locator('#shadow-editor input') + await editor.focus() + await editor.press('k') + expect(await page.evaluate(() => window.hits)).toBe(core === 'candidate' ? 0 : 1) + await expect(editor).toHaveValue(core === 'candidate' ? 'k' : '') + await page.evaluate(() => window.art.destroy()) + }) + + test(`${core}: repeated hotkey init does not multiply the keyboard subscription`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + art.isFocus = true + let hits = 0 + art.hotkey.add('KeyK', () => hits++) + art.hotkey.init() + document.dispatchEvent(new KeyboardEvent('keydown', { code: 'KeyK', bubbles: true, cancelable: true })) + art.destroy() + return hits + })).toBe(core === 'candidate' ? 1 : 2) + }) +} diff --git a/test/browser/input-closeout.spec.js b/test/browser/input-closeout.spec.js new file mode 100644 index 000000000..334bf766b --- /dev/null +++ b/test/browser/input-closeout.spec.js @@ -0,0 +1,175 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, mobile = false) { + if (mobile) + await page.addInitScript(() => Object.defineProperty(navigator, 'userAgent', { configurable: true, value: 'ArtPlayer Android closeout fixture' })) + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => { + window.Artplayer.SCROLL_TIME = 0 + window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, gesture: true }) + window.touch = (target, name, x, y) => { + const event = new Event(name, { bubbles: true }) + Object.defineProperty(event, 'touches', { value: [{ identifier: 1, pageX: x, pageY: y, clientX: x, clientY: y }] }) + target.dispatchEvent(event) + } + }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +test('candidate closeout: restoring a removed default hotkey keeps identity and real playback', async ({ page }) => { + await setup(page) + expect(await page.evaluate(() => { + const art = window.art + const original = art.hotkey.keys.Space[0] + art.hotkey.remove('Space', original) + const absent = !art.hotkey.keys.Space + art.hotkey.init() + art.hotkey.init() + art.isFocus = true + return { absent, count: art.hotkey.keys.Space.length, identity: art.hotkey.keys.Space[0] === original } + })).toEqual({ absent: true, count: 1, identity: true }) + await page.keyboard.press('Space') + await expect.poll(() => page.evaluate(() => window.art.playing)).toBe(true) + await page.evaluate(() => window.art.destroy()) +}) + +test('candidate closeout: a failed native removal remains retryable and releases its record', async ({ page }) => { + await setup(page) + expect(await page.evaluate(() => { + const art = window.art + const target = document.createElement('div') + const remove = target.removeEventListener + const warning = console.warn + const error = new Error('temporary removal failure') + let deny = true + let warnings = 0 + let hits = 0 + console.warn = (message, actual) => { + if (actual === error) + warnings++ + } + target.removeEventListener = function (...args) { + if (deny) + throw error + return remove.apply(this, args) + } + try { + const dispose = art.events.proxy(target, 'example', () => hits++) + art.events.remove(dispose) + const retained = art.events.destroyEvents.has(dispose) + target.dispatchEvent(new Event('example')) + deny = false + art.events.remove(dispose) + target.dispatchEvent(new Event('example')) + const released = !art.events.destroyEvents.has(dispose) + art.destroy() + return { retained, released, warnings, hits } + } + finally { + console.warn = warning + target.removeEventListener = remove + } + })).toEqual({ retained: true, released: true, warnings: 1, hits: 1 }) +}) + +test('candidate closeout: destruction before native add returns cannot leave a late listener', async ({ page }) => { + await setup(page) + expect(await page.evaluate(() => { + const art = window.art + const target = document.createElement('div') + const add = target.addEventListener + let hits = 0 + target.addEventListener = function (...args) { + art.destroy() + return add.apply(this, args) + } + art.events.proxy(target, 'example', () => hits++) + target.dispatchEvent(new Event('example')) + return { hits, remaining: art.events.destroyEvents.size, destroyed: art.isDestroy } + })).toEqual({ hits: 0, remaining: 0, destroyed: true }) +}) + +test('candidate closeout: window registration failure restores the previous global binding', async ({ page }) => { + await setup(page) + expect(await page.evaluate(() => { + const art = window.art + const frame = document.createElement('iframe') + document.body.append(frame) + const next = frame.contentWindow + const add = next.addEventListener + const failure = new Error('window registration failed after add') + next.addEventListener = function (name, ...args) { + add.call(this, name, ...args) + if (name === 'scroll') + throw failure + } + const received = [] + art.on('document:mouseup', event => received.push(event.target === document ? 'old-document' : 'new-document')) + art.on('window:scroll', event => received.push(event.target === window ? 'old-window' : 'new-window')) + let sameError = false + try { + art.events.bindGlobalEvents({ document: next.document, window: next }) + } + catch (error) { + sameError = error === failure + } + next.addEventListener = add + next.document.dispatchEvent(new next.Event('mouseup')) + next.dispatchEvent(new next.Event('scroll')) + document.dispatchEvent(new Event('mouseup')) + window.dispatchEvent(new Event('scroll')) + art.destroy() + frame.remove() + return { sameError, received } + })).toEqual({ sameError: true, received: ['old-document', 'old-window'] }) +}) + +for (const cause of ['source', 'rotation', 'geometry']) { + test(`candidate closeout: ${cause} changes cancel the old gesture in the installed player`, async ({ page }) => { + await setup(page, true) + expect(await page.evaluate((cause) => { + const art = window.art + const video = art.template.$video + let seeks = 0 + art.on('seek', () => seeks++) + window.touch(video, 'touchstart', 100, 100) + if (cause === 'source') + art.url = '/test/pattern.mp4?closeout=source' + if (cause === 'rotation') + art.isRotate = true + if (cause === 'geometry') { + art.template.$player.style.setProperty('width', '0px', 'important') + art.template.$player.style.setProperty('min-width', '0px', 'important') + } + const before = seeks + const width = art.width + window.touch(video, 'touchmove', cause === 'rotation' ? 100 : 140, cause === 'rotation' ? 140 : 100) + art.destroy() + return { newSeeks: seeks - before, zeroWidth: cause !== 'geometry' || width === 0 } + }, cause)).toEqual({ newSeeks: 0, zeroWidth: true }) + }) +} + +test('candidate closeout: adopted viewport retains exact gap boundaries', async ({ page }) => { + await setup(page) + expect(await page.evaluate(async () => { + const art = window.art + const frame = document.createElement('iframe') + frame.style.cssText = 'height:100px;width:200px' + document.body.append(frame) + const container = art.template.$container + container.style.cssText = 'position:absolute;top:150px;left:0;height:20px;width:20px' + frame.contentDocument.body.append(container) + art.events.bindGlobalEvents() + art.constructor.SCROLL_GAP = 50 + const states = [] + art.on('view', value => states.push(value)) + frame.contentWindow.dispatchEvent(new Event('scroll')) + await new Promise(resolve => setTimeout(resolve, 0)) + container.style.top = '151px' + frame.contentWindow.dispatchEvent(new Event('scroll')) + art.destroy() + frame.remove() + return states + })).toEqual([true, false]) +}) diff --git a/test/browser/listener-registry.spec.js b/test/browser/listener-registry.spec.js new file mode 100644 index 000000000..2bd078f83 --- /dev/null +++ b/test/browser/listener-registry.spec.js @@ -0,0 +1,151 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core) { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(() => window.createPlayer('/test/pattern.mp4')) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +for (const core of ['published', 'candidate']) { + test(`${core}: null options preserve the native default and callbacks can be removed directly`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const target = document.createElement('div') + let hits = 0 + let failed = false + const callback = () => hits++ + try { + const remove = art.events.proxy(target, 'example', callback, null) + target.dispatchEvent(new Event('example')) + remove() + target.dispatchEvent(new Event('example')) + } + catch { + failed = true + } + art.destroy() + return { hits, failed } + })).toEqual({ hits: 1, failed: false }) + }) + + test(`${core}: once and abort use native event identity and permit subsequent registration`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const target = document.createElement('div') + const seen = [] + const event = new Event('example') + const callback = function (received) { + seen.push(this === target && received === event) + } + const once = art.events.proxy(target, 'example', callback, { once: true }) + target.dispatchEvent(event) + target.dispatchEvent(event) + once() + const controller = new AbortController() + const aborted = art.events.proxy(target, 'example', callback, { signal: controller.signal }) + target.dispatchEvent(event) + controller.abort() + target.dispatchEvent(event) + aborted() + const skipped = art.events.proxy(target, 'example', callback, { signal: controller.signal }) + target.dispatchEvent(event) + skipped() + art.events.proxy(target, 'example', callback) + target.dispatchEvent(event) + art.destroy() + target.dispatchEvent(event) + return seen + })).toEqual([true, true, true]) + }) + + test(`${core}: direct event disposer preserves native callback identity and releases bookkeeping`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const target = document.createElement('div') + let hits = 0 + const callback = () => hits++ + const before = art.events.destroyEvents.size + const remove = art.events.proxy(target, 'example', callback) + target.removeEventListener('example', callback) + target.dispatchEvent(new Event('example')) + const returned = remove() + const result = { hits, returned: typeof returned, remaining: art.events.destroyEvents.size - before } + art.destroy() + return result + })).toEqual({ hits: 0, returned: 'undefined', remaining: core === 'candidate' ? 0 : 1 }) + }) + + test(`${core}: changing capture options after registration cannot prevent cleanup`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const target = document.createElement('div') + let hits = 0 + const options = { capture: true } + const remove = art.events.proxy(target, 'example', () => hits++, options) + options.capture = false + remove() + target.dispatchEvent(new Event('example')) + art.destroy() + return hits + })).toBe(core === 'candidate' ? 0 : 1) + }) + + test(`${core}: partially failing array registration rolls back the listeners it created`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const target = document.createElement('div') + const original = target.addEventListener + const failure = new Error('second registration denied') + target.addEventListener = function (name, ...args) { + if (name === 'second') + throw failure + return original.call(this, name, ...args) + } + let hits = 0 + let sameError = false + const before = art.events.destroyEvents.size + try { + art.events.proxy(target, ['first', 'second'], () => hits++) + } + catch (error) { + sameError = error === failure + } + target.addEventListener = original + target.dispatchEvent(new Event('first')) + const result = { hits, sameError, remaining: art.events.destroyEvents.size - before } + art.destroy() + return result + })).toEqual({ hits: core === 'candidate' ? 0 : 1, sameError: true, remaining: core === 'candidate' ? 0 : 1 }) + }) + + test(`${core}: registration throwing after native add does not leave an untracked listener`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const target = document.createElement('div') + const original = target.addEventListener + const failure = new Error('after native add') + target.addEventListener = function (...args) { + original.apply(this, args) + throw failure + } + let hits = 0 + let sameError = false + try { + art.events.proxy(target, 'example', () => hits++) + } + catch (error) { + sameError = error === failure + } + target.addEventListener = original + target.dispatchEvent(new Event('example')) + art.destroy() + return { hits, sameError } + })).toEqual({ hits: core === 'candidate' ? 0 : 1, sameError: true }) + }) +} diff --git a/test/browser/pointer-events.spec.js b/test/browser/pointer-events.spec.js new file mode 100644 index 000000000..451e96603 --- /dev/null +++ b/test/browser/pointer-events.spec.js @@ -0,0 +1,112 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core, mobile = false) { + if (mobile) + await page.addInitScript(() => Object.defineProperty(navigator, 'userAgent', { configurable: true, value: 'ArtPlayer Android pointer fixture' })) + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(() => window.createPlayer('/test/pattern.mp4')) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +for (const core of ['published', 'candidate']) { + test(`${core}: real mouse input focuses the player, hovers and toggles actual playback`, async ({ page }) => { + await setup(page, core) + await page.evaluate(() => { + window.art.constructor.DBCLICK_FULLSCREEN = false + window.art.constructor.DBCLICK_TIME = 0 + window.pointerTrusted = [] + window.art.on('click', event => window.pointerTrusted.push(event.isTrusted)) + }) + const video = page.locator('.art-video') + await video.click({ position: { x: 100, y: 100 } }) + await expect.poll(() => page.evaluate(() => window.art.playing)).toBe(true) + expect(await page.evaluate(() => ({ focus: window.art.isFocus, hover: window.art.template.$player.classList.contains('art-hover') }))).toEqual({ focus: true, hover: true }) + await video.click({ position: { x: 100, y: 100 } }) + await expect.poll(() => page.evaluate(() => window.art.template.$video.paused)).toBe(true) + expect(await page.evaluate(() => window.pointerTrusted)).toEqual([true, true]) + await page.mouse.move(1, 1) + await expect.poll(() => page.evaluate(() => window.art.template.$player.classList.contains('art-hover'))).toBe(false) + await page.evaluate(() => window.art.destroy()) + }) + + test(`${core}: click pairs preserve callback identity and playback ordering`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + art.constructor.DBCLICK_TIME = 60000 + art.constructor.DBCLICK_FULLSCREEN = false + const calls = [] + const events = [new MouseEvent('click'), new MouseEvent('click'), new MouseEvent('click')] + let current + art.template.$video.play = () => { + calls.push('play') + return Promise.resolve() + } + for (const name of ['click', 'dblclick']) { + art.on(name, function (event) { + calls.push(`${name}:${event === current}:${this === art}`) + }, art) + } + for (const event of events) { + current = event + art.template.$video.dispatchEvent(event) + } + art.destroy() + return calls + })).toEqual(['click:true:true', 'play', 'dblclick:true:true', 'click:true:true', 'play']) + }) + + for (const name of ['click', 'dblclick']) { + test(`${core}: destruction in ${name} stops its subsequent default action`, async ({ page }) => { + await setup(page, core, name === 'dblclick') + expect(await page.evaluate((name) => { + const art = window.art + art.constructor.DBCLICK_TIME = 60000 + let plays = 0 + art.template.$video.play = () => { + plays++ + return Promise.resolve() + } + art.on(name, () => art.destroy()) + const video = art.template.$video + video.dispatchEvent(new MouseEvent('click')) + if (name === 'dblclick') + video.dispatchEvent(new MouseEvent('click')) + return { plays, destroyed: art.isDestroy } + }, name)).toEqual({ plays: core === 'published' ? 1 : 0, destroyed: true }) + }) + } + + test(`${core}: focus, hover and move preserve flags, classes and original events`, async ({ page }) => { + await setup(page, core) + expect(await page.evaluate(() => { + const art = window.art + const { $player } = art.template + const input = document.createElement('input') + $player.append(input) + const calls = [] + let expected + for (const name of ['focus', 'blur', 'mousemove']) + art.on(name, event => calls.push([name, event === expected, art.isFocus, art.isInput])) + art.on('hover', (state, event) => calls.push(['hover', state, event === expected, $player.classList.contains('art-hover')])) + expected = new MouseEvent('click', { bubbles: true }) + input.dispatchEvent(expected) + expected = new MouseEvent('contextmenu', { bubbles: true }) + document.body.dispatchEvent(expected) + expected = new MouseEvent('mouseenter') + $player.dispatchEvent(expected) + expected = new MouseEvent('mousemove') + $player.dispatchEvent(expected) + expected = new MouseEvent('mouseleave') + $player.dispatchEvent(expected) + art.destroy() + return calls + })).toEqual([ + ['focus', true, true, true], + ['blur', true, false, false], + ['hover', true, true, true], + ['mousemove', true, false, false], + ['hover', false, true, false], + ]) + }) +} diff --git a/test/event-scheduling.test.js b/test/event-scheduling.test.js new file mode 100644 index 000000000..9bf518e72 --- /dev/null +++ b/test/event-scheduling.test.js @@ -0,0 +1,223 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { resizeInit, viewInit, updateInit, inViewport, Emitter, beginLifecycle, getScope } = await loadModules({ + resizeInit: 'packages/artplayer/src/events/resizeInit', + viewInit: 'packages/artplayer/src/events/viewInit', + updateInit: 'packages/artplayer/src/events/updateInit', + inViewport: { file: 'packages/artplayer/src/events/viewport', name: 'inViewport' }, + Emitter: 'packages/artplayer/src/utils/emitter', + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, +}) + +function fixture(t) { + const timers = new Map() + const frames = new Map() + let id = 0 + t.mock.method(globalThis, 'setTimeout', (callback, delay) => { + const key = ++id + timers.set(key, { callback, delay }) + return key + }) + t.mock.method(globalThis, 'clearTimeout', key => timers.delete(key)) + for (const [name, value] of Object.entries({ + requestAnimationFrame(callback) { + const key = ++id + frames.set(key, callback) + return key + }, + cancelAnimationFrame: key => frames.delete(key), + })) { + const before = Object.getOwnPropertyDescriptor(globalThis, name) + Object.defineProperty(globalThis, name, { configurable: true, value }) + t.after(() => before ? Object.defineProperty(globalThis, name, before) : Reflect.deleteProperty(globalThis, name)) + } + const orientation = new EventTarget() + orientation.onchange = null + const document = { defaultView: { innerHeight: 100, innerWidth: 200, screen: { orientation } }, documentElement: { clientHeight: 80, clientWidth: 160 } } + const rect = { top: 0, left: 0, width: 20, height: 20 } + const container = { ownerDocument: document, getBoundingClientRect: () => rect } + const calls = [] + const art = Object.assign(new Emitter(), { + template: { $player: { ownerDocument: document }, $container: container }, + constructor: { RESIZE_TIME: 10, SCROLL_TIME: 20, SCROLL_GAP: 0, USE_RAF: true }, + option: { autoSize: true, autoMini: true }, + aspectRatio: '16:9', + state: 'standard', + autoSize: () => calls.push('autoSize'), + mini: false, + playing: false, + notice: { show: 'before' }, + }) + beginLifecycle(art) + const scope = getScope(art) + const registry = { proxy(target, name, callback) { + target.addEventListener(name, callback) + scope.add(() => { + target.removeEventListener(name, callback) + }) + } } + const flushTimers = () => { + const pending = [...timers.values()] + timers.clear() + for (const timer of pending) + timer.callback() + } + const frame = () => { + const [key, callback] = frames.entries().next().value + frames.delete(key) + callback(0) + } + return { art, scope, registry, calls, timers, frames, frame, flushTimers, orientation, rect, document } +} + +test('resize coalesces with live delay, preserves normal effects and cancels on destruction', (t) => { + const f = fixture(t) + resizeInit(f.art, f.registry) + f.art.on('resize', () => f.calls.push('resize')) + f.art.emit('window:resize', new Event('resize')) + f.art.emit('window:orientationchange', new Event('orientationchange')) + assert.equal(f.timers.size, 1) + assert.equal([...f.timers.values()][0].delay, 10) + f.art.constructor.RESIZE_TIME = 30 + f.art.emit('window:resize', new Event('resize')) + assert.equal([...f.timers.values()][0].delay, 30) + f.flushTimers() + assert.deepEqual(f.calls, ['autoSize', 'resize']) + assert.equal(f.art.aspectRatio, '16:9') + assert.equal(f.art.notice.show, '') + f.art.emit('window:resize', new Event('resize')) + f.scope.dispose() + assert.equal(f.timers.size, 0) + f.art.emit('window:resize', new Event('resize')) + assert.equal(f.timers.size, 0) +}) + +test('orientation event capability does not depend on onchange being assigned', (t) => { + const f = fixture(t) + resizeInit(f.art, f.registry) + f.orientation.dispatchEvent(new Event('change')) + assert.equal(f.timers.size, 1) + f.flushTimers() + assert.deepEqual(f.calls, ['autoSize']) + f.scope.dispose() + f.orientation.dispatchEvent(new Event('change')) + assert.equal(f.timers.size, 0) +}) + +test('destroy inside auto-size prevents later ratio and notice writes', (t) => { + const f = fixture(t) + let ratioWrites = 0 + Object.defineProperty(f.art, 'aspectRatio', { get: () => '16:9', set: () => ratioWrites++ }) + f.art.autoSize = () => f.scope.dispose() + resizeInit(f.art, f.registry) + f.art.emit('resize') + assert.equal(ratioWrites, 0) + assert.equal(f.art.notice.show, 'before') +}) + +test('view preserves leading-only throttle, initial delay and live gap while cleaning its timer', (t) => { + const f = fixture(t) + const seen = [] + viewInit(f.art) + f.art.on('view', value => seen.push(value)) + f.art.constructor.SCROLL_TIME = 99 + f.art.emit('window:scroll', new Event('scroll')) + f.art.emit('window:scroll', new Event('scroll')) + assert.deepEqual(seen, [true]) + assert.equal([...f.timers.values()][0].delay, 20) + f.rect.top = 130 + f.flushTimers() + assert.deepEqual(seen, [true]) + f.art.emit('window:scroll', new Event('scroll')) + assert.deepEqual(seen, [true, false]) + assert.equal(f.art.mini, true) + f.flushTimers() + f.art.constructor.SCROLL_GAP = 50 + f.art.emit('window:scroll', new Event('scroll')) + assert.deepEqual(seen, [true, false, true]) + f.scope.dispose() + assert.equal(f.timers.size, 0) + f.art.emit('window:scroll', new Event('scroll')) + assert.deepEqual(seen, [true, false, true]) +}) + +test('view callback failure remains synchronous and does not lock the throttle', (t) => { + const f = fixture(t) + viewInit(f.art) + const error = new Error('view failed') + f.art.once('view', () => { + throw error + }) + assert.throws(() => f.art.emit('window:scroll', new Event('scroll')), actual => actual === error) + assert.equal(f.timers.size, 0) + f.art.emit('window:scroll', new Event('scroll')) + assert.equal(f.timers.size, 1) + f.scope.dispose() +}) + +test('nested leading view dispatch keeps its timing and destroy prevents reset timers', (t) => { + const f = fixture(t) + viewInit(f.art) + let views = 0 + f.art.on('view', () => views++) + f.art.once('view', () => f.art.emit('window:scroll', new Event('scroll'))) + f.art.emit('window:scroll', new Event('scroll')) + assert.equal(views, 2) + assert.equal(f.timers.size, 2) + f.flushTimers() + f.art.once('view', () => f.scope.dispose()) + f.art.emit('window:scroll', new Event('scroll')) + assert.equal(f.timers.size, 0) +}) + +test('RAF keeps the initial playing emission and one frame while cancelling reentrant destruction', (t) => { + const f = fixture(t) + let frames = 0 + f.art.playing = true + f.art.on('raf', () => frames++) + updateInit(f.art) + assert.equal(frames, 1) + assert.equal(f.frames.size, 1) + f.art.playing = false + f.frame() + assert.equal(frames, 1) + assert.equal(f.frames.size, 1) + f.art.playing = true + f.art.once('raf', () => f.scope.dispose()) + f.frame() + assert.equal(frames, 2) + assert.equal(f.frames.size, 0) +}) + +test('RAF remains opt-in and explicit destroy notification can cancel an idle frame', (t) => { + const f = fixture(t) + f.art.constructor.USE_RAF = false + updateInit(f.art) + assert.equal(f.frames.size, 0) + f.art.constructor.USE_RAF = true + updateInit(f.art) + assert.equal(f.frames.size, 1) + f.art.emit('destroy') + assert.equal(f.frames.size, 0) + f.scope.dispose() +}) + +test('viewport follows owner document changes and preserves edge/gap arithmetic', (t) => { + const f = fixture(t) + const container = f.art.template.$container + f.rect.top = 150 + assert.equal(inViewport(container, 50), true) + f.rect.top = 151 + assert.equal(inViewport(container, 50), false) + container.ownerDocument = { defaultView: null, documentElement: { clientHeight: 200, clientWidth: 200 } } + assert.equal(inViewport(container, 0), true) + f.rect.left = 301 + assert.equal(inViewport(container, 50), false) + f.rect.left = 300 + assert.equal(inViewport(container, 50), true) + f.scope.dispose() +}) diff --git a/test/gesture.test.js b/test/gesture.test.js new file mode 100644 index 000000000..c6a167196 --- /dev/null +++ b/test/gesture.test.js @@ -0,0 +1,215 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const savedAgent = Object.getOwnPropertyDescriptor(globalThis, 'CUSTOM_USER_AGENT') +Object.defineProperty(globalThis, 'CUSTOM_USER_AGENT', { configurable: true, value: 'ArtPlayer Android gesture unit fixture' }) +let modules +try { + modules = await loadModules({ + gestureController: { file: 'packages/artplayer/src/input/gesture-controller', name: 'gestureController' }, + slideDirection: { file: 'packages/artplayer/src/input/gesture-direction', name: 'slideDirection' }, + gestureInit: 'packages/artplayer/src/events/gestureInit', + 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' }, + }) +} +finally { + if (savedAgent) + Object.defineProperty(globalThis, 'CUSTOM_USER_AGENT', savedAgent) + else + delete globalThis.CUSTOM_USER_AGENT +} +const { gestureController, slideDirection, gestureInit, Emitter, beginLifecycle, getScope, beginSource } = modules + +function touch(x, y, identifier = 1, count = 1) { + return { touches: Array.from({ length: count }, () => ({ pageX: x, pageY: y, clientX: x, clientY: y, identifier })) } +} + +function fixture() { + const calls = [] + const art = Object.assign(new Emitter(), { + template: { $video: {}, $progress: { clientWidth: 100, getBoundingClientRect: () => ({ left: 10 }) } }, + option: { isLive: false, gesture: true }, + constructor: { TOUCH_MOVE_RATIO: 0.5 }, + currentTime: 20, + duration: 100, + width: 200, + height: 100, + top: 10, + isRotate: false, + isLock: false, + notice: { show: '' }, + }) + // eslint-disable-next-line accessor-pairs -- The real seek API is write-only. + Object.defineProperty(art, 'seek', { + set(time) { + art.currentTime = time + calls.push(['seek', time]) + art.emit('seek', time) + }, + }) + art.on('setBar', (kind, value, event) => calls.push(['bar', kind, value, event])) + beginLifecycle(art) + const gesture = gestureController(art) + return { art, gesture, calls, dispose: () => getScope(art).dispose() } +} + +test('gesture directions retain the two-pixel threshold and exact diagonal boundaries', () => { + for (const [x, y, expected] of [[1, 1, 0], [2, 0, 4], [0, 2, 2], [-2, 0, 3], [0, -2, 1], [2, 2, 4], [2, -2, 1], [-2, -2, 3], [-2, 2, 2]]) + assert.equal(slideDirection(0, 0, x, y), expected) + assert.equal(slideDirection(0, 0, Number.NaN, 0), 0) +}) + +test('video dragging retains seek/bar/notice values and clamps against duration', () => { + const f = fixture() + const event = touch(40, 0) + f.gesture.start(f.art.template.$video, touch(0, 0)) + f.gesture.move(event) + assert.deepEqual(f.calls, [['seek', 30], ['bar', 'played', 0.3, event]]) + assert.equal(f.art.notice.show, '00:30 / 01:40') + f.art.constructor.TOUCH_MOVE_RATIO = 2 + f.gesture.move(touch(1000, 0)) + assert.equal(f.art.currentTime, 100) + f.dispose() +}) + +test('progress start retains bar-before-seek and its full-width drag multiplier', () => { + const f = fixture() + const event = touch(60, 20) + f.gesture.start(f.art.template.$progress, event) + assert.deepEqual(f.calls, [['bar', 'played', 0.5, event], ['seek', 50]]) + f.gesture.move(touch(100, 20)) + assert.equal(f.art.currentTime, 70) + f.dispose() +}) + +test('rotation uses the vertical axis for absolute progress and subsequent drag', () => { + const f = fixture() + f.art.isRotate = true + f.gesture.start(f.art.template.$progress, touch(60, 60)) + assert.equal(f.art.currentTime, 50) + f.gesture.move(touch(90, 60)) + assert.equal(f.art.currentTime, 50) + f.gesture.move(touch(60, 80)) + assert.equal(f.art.currentTime, 70) + f.dispose() +}) + +test('cancel, lock, multitouch, changed finger, source and rotation cannot resume the old drag', () => { + for (const reason of ['cancel', 'lock', 'multitouch', 'identifier', 'source', 'rotation']) { + const f = fixture() + f.gesture.start(f.art.template.$video, touch(0, 0)) + if (reason === 'cancel') + f.art.emit('document:touchcancel', {}) + if (reason === 'lock') { + f.art.isLock = true + f.art.emit('lock', true) + f.art.isLock = false + } + if (reason === 'multitouch') + f.gesture.move(touch(10, 0, 1, 2)) + if (reason === 'identifier') + f.gesture.move(touch(10, 0, 2)) + if (reason === 'source') + beginSource(f.art) + if (reason === 'rotation') + f.art.isRotate = true + f.gesture.move(touch(40, 0)) + assert.equal(f.art.currentTime, 20, reason) + f.dispose() + } +}) + +test('non-finite or zero geometry cancels movement instead of producing invalid positions', () => { + for (const [key, value] of [['width', 0], ['width', Infinity], ['duration', Infinity], ['duration', 0]]) { + const f = fixture() + f.gesture.start(f.art.template.$video, touch(0, 0)) + const before = f.art[key] + f.art[key] = value + f.gesture.move(touch(40, 0)) + f.art[key] = before + f.gesture.move(touch(60, 0)) + assert.deepEqual(f.calls, [], key) + f.dispose() + } + const f = fixture() + f.art.template.$progress.clientWidth = 0 + f.gesture.start(f.art.template.$progress, touch(60, 0)) + assert.deepEqual(f.calls, []) + f.dispose() +}) + +test('destroy inside absolute progress notification prevents the following seek', () => { + const f = fixture() + f.art.on('setBar', f.dispose) + f.gesture.start(f.art.template.$progress, touch(60, 0)) + assert.equal(f.art.currentTime, 20) + assert.equal(f.calls.length, 1) + f.gesture.move(touch(80, 0)) + assert.equal(f.calls.length, 1) +}) + +test('destroy inside relative seek prevents bar and notice updates', () => { + const f = fixture() + f.art.on('seek', f.dispose) + f.gesture.start(f.art.template.$video, touch(0, 0)) + f.gesture.move(touch(40, 0)) + assert.deepEqual(f.calls, [['seek', 30]]) + assert.equal(f.art.notice.show, '') +}) + +test('nested touch start supersedes the interrupted absolute progress transaction', () => { + const f = fixture() + f.art.once('setBar', () => f.gesture.start(f.art.template.$video, touch(0, 0, 2))) + f.gesture.start(f.art.template.$progress, touch(60, 0)) + assert.equal(f.art.currentTime, 20) + f.gesture.move(touch(40, 0, 2)) + assert.equal(f.art.currentTime, 30) + f.dispose() +}) + +test('failed progress start retains the caller error and cancels the unfinished drag', () => { + const f = fixture() + const error = new Error('progress callback failed') + f.art.once('setBar', () => { + throw error + }) + assert.throws(() => f.gesture.start(f.art.template.$progress, touch(60, 0)), thrown => thrown === error) + f.gesture.move(touch(80, 0)) + assert.equal(f.art.currentTime, 20) + f.dispose() +}) + +test('touch end and owner disposal remove internal subscriptions but preserve external listeners', () => { + const f = fixture() + let external = 0 + f.art.on('document:touchend', () => external++) + f.gesture.start(f.art.template.$video, touch(0, 0)) + f.art.emit('document:touchend', {}) + f.gesture.move(touch(40, 0)) + assert.equal(f.art.currentTime, 20) + f.dispose() + f.art.emit('document:touchend', {}) + assert.equal(external, 2) + assert.equal(f.art.e['document:touchcancel'], undefined) + assert.equal(f.art.e.lock, undefined) +}) + +test('mobile gesture=false still installs progress interactions, while live mode installs none', () => { + const f = fixture() + f.art.option.gesture = false + const registrations = [] + const events = { proxy: (target, name) => registrations.push([target, name]) } + gestureInit(f.art, events) + assert.deepEqual(registrations.map(item => item[1]), ['touchstart', 'touchmove', 'touchcancel']) + assert(registrations.every(item => item[0] === f.art.template.$progress)) + f.art.option.isLive = true + registrations.length = 0 + gestureInit(f.art, events) + assert.deepEqual(registrations, []) + f.dispose() +}) diff --git a/test/global-events.test.js b/test/global-events.test.js new file mode 100644 index 000000000..d4863eaa3 --- /dev/null +++ b/test/global-events.test.js @@ -0,0 +1,133 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { globalInit, ownListeners, proxyListener, removeListener, destroyListeners, beginLifecycle, getScope } = await loadModules({ + globalInit: 'packages/artplayer/src/events/globalInit', + ...Object.fromEntries(['ownListeners', 'proxyListener', 'removeListener', 'destroyListeners'].map(name => [name, { file: 'packages/artplayer/src/events/listener-registry', name }])), + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, +}) + +function source() { + const window = new EventTarget() + const document = Object.assign(new EventTarget(), { defaultView: window }) + return { document, window } +} + +function fixture() { + const initial = source() + const received = [] + const art = { + template: { $player: { ownerDocument: initial.document } }, + emit: (...args) => received.push(args), + } + beginLifecycle(art) + const registry = { destroyEvents: new Set() } + ownListeners(registry, art) + registry.proxy = (...args) => proxyListener(registry, ...args) + registry.remove = dispose => removeListener(registry, dispose) + const scope = getScope(art) + scope.add(() => { + destroyListeners(registry) + return undefined + }) + globalInit(art, registry) + return { initial, art, registry, scope, received } +} + +test('global rebinding selects current owner targets, keeps event identity and original window fallback', () => { + const f = fixture() + const next = source() + const event = new Event('mouseup') + const scroll = new Event('scroll') + f.registry.bindGlobalEvents({ document: next.document }) + f.initial.document.dispatchEvent(new Event('mouseup')) + next.document.dispatchEvent(event) + next.window.dispatchEvent(new Event('scroll')) + f.initial.window.dispatchEvent(scroll) + assert.deepEqual(f.received, [['document:mouseup', event], ['window:scroll', scroll]]) + f.art.template.$player.ownerDocument = next.document + f.registry.bindGlobalEvents() + f.initial.window.dispatchEvent(new Event('scroll')) + next.window.dispatchEvent(scroll) + assert.equal(f.received.length, 3) + f.scope.dispose() + next.document.dispatchEvent(event) + assert.equal(f.received.length, 3) + assert.equal(f.registry.destroyEvents.size, 0) +}) + +test('window registration failure rolls back the staged document while old listeners keep working', () => { + const f = fixture() + const next = source() + const failure = new Error('window failure') + next.window.addEventListener = () => { + throw failure + } + assert.throws(() => f.registry.bindGlobalEvents(next), error => error === failure) + const event = new Event('mouseup') + next.document.dispatchEvent(new Event('mouseup')) + f.initial.document.dispatchEvent(event) + assert.deepEqual(f.received, [['document:mouseup', event]]) + assert.equal(f.registry.destroyEvents.size, 15) + f.scope.dispose() +}) + +test('staged listeners do not forward before commit while the previous binding remains active', () => { + const f = fixture() + const next = source() + const original = next.window.addEventListener + const oldEvent = new Event('mouseup') + next.window.addEventListener = function (name, ...args) { + if (name === 'resize') { + next.document.dispatchEvent(new Event('mouseup')) + f.initial.document.dispatchEvent(oldEvent) + } + return original.call(this, name, ...args) + } + f.registry.bindGlobalEvents(next) + assert.deepEqual(f.received, [['document:mouseup', oldEvent]]) + const nextEvent = new Event('mouseup') + next.document.dispatchEvent(nextEvent) + f.initial.document.dispatchEvent(new Event('mouseup')) + assert.deepEqual(f.received, [['document:mouseup', oldEvent], ['document:mouseup', nextEvent]]) + f.scope.dispose() +}) + +test('a newer reentrant global binding wins and the interrupted registration is released', () => { + const f = fixture() + const interrupted = source() + const newest = source() + const original = interrupted.document.addEventListener + interrupted.document.addEventListener = function (name, ...args) { + if (name === 'click') + f.registry.bindGlobalEvents(newest) + return original.call(this, name, ...args) + } + f.registry.bindGlobalEvents(interrupted) + f.initial.document.dispatchEvent(new Event('mouseup')) + interrupted.document.dispatchEvent(new Event('mouseup')) + const event = new Event('mouseup') + newest.document.dispatchEvent(event) + assert.deepEqual(f.received, [['document:mouseup', event]]) + assert.equal(f.registry.destroyEvents.size, 15) + f.scope.dispose() +}) + +test('destroy during rebinding clears staged and old listeners and later bind remains inert', () => { + const f = fixture() + const next = source() + const original = next.document.addEventListener + next.document.addEventListener = function (...args) { + f.scope.dispose() + return original.apply(this, args) + } + f.registry.bindGlobalEvents(next) + assert.equal(f.registry.destroyEvents.size, 0) + f.registry.bindGlobalEvents() + f.initial.document.dispatchEvent(new Event('mouseup')) + next.document.dispatchEvent(new Event('mouseup')) + assert.deepEqual(f.received, []) +}) diff --git a/test/hotkey.test.js b/test/hotkey.test.js new file mode 100644 index 000000000..d8feade80 --- /dev/null +++ b/test/hotkey.test.js @@ -0,0 +1,168 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { Hotkey, Emitter, beginLifecycle, getScope } = await loadModules({ + Hotkey: 'packages/artplayer/src/hotkey', + Emitter: 'packages/artplayer/src/utils/emitter', + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, +}) + +function fixture(enabled = true) { + const document = { activeElement: { nodeType: 1, tagName: 'BODY', isContentEditable: false } } + const art = Object.assign(new Emitter(), { + template: { $player: { ownerDocument: document } }, + constructor: { SEEK_STEP: 5, VOLUME_STEP: 0.1 }, + option: { hotkey: enabled }, + isFocus: true, + fullscreenWeb: true, + volume: 0.5, + toggle: () => undefined, + }) + beginLifecycle(art) + const hotkey = new Hotkey(art) + function dispatch(code = 'KeyK', options = {}) { + const event = Object.assign(new Event('keydown', { cancelable: true }), { code, ...options }) + art.emit('document:keydown', event) + return event + } + return { art, hotkey, document, dispatch, dispose: () => getScope(art).dispose() } +} + +test('hotkeys preserve own art/keys fields, public prototype and registration identity', () => { + const f = fixture() + assert.deepEqual(Object.keys(f.hotkey), ['art', 'keys']) + assert.deepEqual(Object.getOwnPropertyNames(Hotkey.prototype), ['constructor', 'init', 'add', 'remove']) + assert.equal(Object.getPrototypeOf(f.hotkey.keys), Object.prototype) + for (const key of ['__proto__', 'constructor', 'toString']) { + const callback = () => {} + assert.equal(f.hotkey.add(key, callback), f.hotkey) + const array = f.hotkey.keys[key] + f.hotkey.add(key, callback) + assert.equal(array.length, 1) + assert.equal(f.hotkey.remove(key, callback), f.hotkey) + assert.deepEqual(array, []) + assert.equal(Object.hasOwn(f.hotkey.keys, key), false) + } + assert.equal(Object.getPrototypeOf(f.hotkey.keys), Object.prototype) + f.dispose() +}) + +test('default hotkeys preserve live constants, operations and inactive focus behavior', () => { + const f = fixture() + f.dispatch('Escape') + assert.equal(f.art.fullscreenWeb, false) + f.art.constructor.SEEK_STEP = 9 + f.dispatch('ArrowLeft') + f.dispatch('ArrowRight') + assert.equal(f.art.backward, 9) + assert.equal(f.art.forward, 9) + f.dispatch('ArrowUp') + assert.equal(f.art.volume, 0.6) + f.art.isFocus = false + assert.equal(f.dispatch('ArrowDown').defaultPrevented, false) + assert.equal(f.art.volume, 0.6) + f.dispose() +}) + +test('default disabling still permits custom keys and later initialization installs defaults once', () => { + const f = fixture(false) + assert.deepEqual(Object.keys(f.hotkey.keys), []) + let hits = 0 + f.hotkey.add('KeyK', () => hits++) + f.dispatch() + f.art.option.hotkey = true + f.hotkey.init() + f.hotkey.init() + f.dispatch() + assert.equal(hits, 2) + assert.equal(f.hotkey.keys.Space.length, 1) + f.dispose() +}) + +test('explicit reinitialization restores removed defaults without adding duplicate callbacks', () => { + const f = fixture() + const callback = f.hotkey.keys.ArrowRight[0] + f.hotkey.remove('ArrowRight', callback) + assert.equal(f.hotkey.keys.ArrowRight, undefined) + f.hotkey.init() + f.hotkey.init() + assert.deepEqual(f.hotkey.keys.ArrowRight, [callback]) + assert.equal(f.hotkey.keys.Space.length, 1) + f.dispatch('ArrowRight') + assert.equal(f.art.forward, 5) + f.dispose() +}) + +test('key dispatch retains callback receiver, event order and live-array removal behavior', () => { + const f = fixture() + const calls = [] + function first(event) { + calls.push(['first', this === f.art, event.defaultPrevented]) + f.hotkey.remove('KeyK', first) + } + f.hotkey.add('KeyK', first) + f.hotkey.add('KeyK', () => calls.push('second')) + f.art.on('hotkey', () => calls.push('hotkey')) + f.art.on('keydown', () => calls.push('keydown')) + f.dispatch() + f.dispatch() + assert.deepEqual(calls, [['first', true, true], 'hotkey', 'keydown', 'second', 'hotkey', 'keydown']) + f.dispose() +}) + +test('destroy during a hotkey stops later callbacks and public notifications', () => { + const f = fixture() + const calls = [] + f.hotkey.add('KeyK', () => { + calls.push('first') + f.dispose() + }) + f.hotkey.add('KeyK', () => calls.push('second')) + f.art.on('hotkey', () => calls.push('hotkey')) + f.art.on('keydown', () => calls.push('keydown')) + f.dispatch() + f.hotkey.init() + f.dispatch() + assert.deepEqual(calls, ['first']) + assert.equal(f.art.e['document:keydown'], undefined) +}) + +test('synchronous hotkey errors retain identity and do not emit success notifications', () => { + const f = fixture() + const error = new Error('callback failed') + f.hotkey.add('KeyK', () => { + throw error + }) + let downstream = 0 + f.art.on('hotkey', () => downstream++) + f.art.on('keydown', () => downstream++) + assert.throws(() => f.dispatch(), value => value === error) + assert.equal(downstream, 0) + f.dispose() +}) + +test('modifiers and composition suppress hotkeys but preserve generic keydown delivery', () => { + const f = fixture() + let keys = 0 + let generic = 0 + f.hotkey.add('KeyK', () => keys++) + f.art.on('keydown', () => generic++) + for (const options of [{ altKey: true }, { ctrlKey: true }, { metaKey: true }, { shiftKey: true }, { isComposing: true }, { keyCode: 229 }]) + assert.equal(f.dispatch('KeyK', options).defaultPrevented, false) + assert.equal(keys, 0) + assert.equal(generic, 6) + f.dispose() +}) + +test('an absent active element still permits a focused player key without throwing', () => { + const f = fixture() + f.document.activeElement = null + let hits = 0 + f.hotkey.add('KeyK', () => hits++) + assert.equal(f.dispatch().defaultPrevented, true) + assert.equal(hits, 1) + f.dispose() +}) diff --git a/test/listener-registry.test.js b/test/listener-registry.test.js new file mode 100644 index 000000000..acb542a7c --- /dev/null +++ b/test/listener-registry.test.js @@ -0,0 +1,201 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { ownListeners, proxyListener, removeListener, destroyListeners, beginLifecycle, getScope } = await loadModules({ + ...Object.fromEntries(['ownListeners', 'proxyListener', 'removeListener', 'destroyListeners'].map(name => [name, { file: 'packages/artplayer/src/events/listener-registry', name }])), + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, +}) + +function fixture() { + const art = {} + beginLifecycle(art) + const registry = { destroyEvents: new Set() } + ownListeners(registry, art) + const scope = getScope(art) + scope.add(() => { + destroyListeners(registry) + return undefined + }) + return { registry, scope, target: new EventTarget() } +} + +test('native callbacks keep identity, receiver and event; direct disposal is idempotent', () => { + const { registry, target, scope } = fixture() + const received = [] + function callback(event) { + received.push([this, event]) + } + const dispose = proxyListener(registry, target, 'example', callback) + const event = new Event('example') + target.dispatchEvent(event) + assert.deepEqual(received, [[target, event]]) + target.removeEventListener('example', callback) + target.dispatchEvent(event) + assert.equal(received.length, 1) + assert.equal(dispose(), undefined) + assert.equal(dispose(), undefined) + assert.equal(registry.destroyEvents.size, 0) + scope.dispose() +}) + +test('capture is read once and removal uses the registration snapshot', () => { + const { registry, scope } = fixture() + const calls = [] + const target = { + addEventListener: (...args) => calls.push(['add', ...args]), + removeEventListener: (...args) => calls.push(['remove', ...args]), + } + let reads = 0 + const callback = () => {} + const options = { + get capture() { return ++reads === 1 }, + once: true, + passive: false, + } + proxyListener(registry, target, 'example', callback, options)() + assert.equal(reads, 1) + assert.deepEqual(calls, [ + ['add', 'example', callback, { capture: true, once: true, passive: false, signal: undefined }], + ['remove', 'example', callback, true], + ]) + scope.dispose() +}) + +test('once and object listeners use native dispatch; explicit disposal clears their records', () => { + const { registry, target, scope } = fixture() + const listener = { + hits: 0, + handleEvent() { this.hits++ }, + } + const dispose = proxyListener(registry, target, 'example', listener, { once: true }) + target.dispatchEvent(new Event('example')) + target.dispatchEvent(new Event('example')) + assert.equal(listener.hits, 1) + assert.equal(registry.destroyEvents.has(dispose), true) + dispose() + assert.equal(registry.destroyEvents.size, 0) + scope.dispose() +}) + +test('aborted signals skip registration and later abort clears the owned record', () => { + const { registry, target, scope } = fixture() + let hits = 0 + const controller = new AbortController() + proxyListener(registry, target, 'example', () => hits++, { signal: controller.signal }) + target.dispatchEvent(new Event('example')) + controller.abort() + target.dispatchEvent(new Event('example')) + assert.equal(hits, 1) + assert.equal(registry.destroyEvents.size, 0) + proxyListener(registry, target, 'example', () => hits++, { signal: controller.signal }) + target.dispatchEvent(new Event('example')) + assert.equal(hits, 1) + assert.equal(registry.destroyEvents.size, 0) + scope.dispose() +}) + +test('registration failure after native add rolls back an entire array and keeps error identity', () => { + const { registry, target, scope } = fixture() + const original = target.addEventListener + const failure = new Error('registration failed') + target.addEventListener = function (name, ...args) { + original.call(this, name, ...args) + if (name === 'second') + throw failure + } + let hits = 0 + assert.throws(() => proxyListener(registry, target, ['first', 'second'], () => hits++), error => error === failure) + target.dispatchEvent(new Event('first')) + target.dispatchEvent(new Event('second')) + assert.equal(hits, 0) + assert.equal(registry.destroyEvents.size, 0) + scope.dispose() +}) + +test('destruction during native registration removes a listener added after cleanup', () => { + const { registry, target, scope } = fixture() + const original = target.addEventListener + target.addEventListener = function (...args) { + scope.dispose() + original.apply(this, args) + } + let hits = 0 + proxyListener(registry, target, 'example', () => hits++) + target.dispatchEvent(new Event('example')) + assert.equal(hits, 0) + assert.equal(registry.destroyEvents.size, 0) + assert.equal(scope.closed, true) +}) + +test('failed removal retains a retryable record and does not prevent other cleanup', (t) => { + const { registry, target, scope } = fixture() + const failure = new Error('temporary removal failure') + const warnings = [] + t.mock.method(console, 'warn', (...args) => warnings.push(args)) + const original = target.removeEventListener + let denied = true + target.removeEventListener = function (name, ...args) { + if (denied && name === 'first') + throw failure + original.call(this, name, ...args) + } + const calls = [] + const first = proxyListener(registry, target, 'first', () => calls.push('first')) + proxyListener(registry, target, 'second', () => calls.push('second')) + removeListener(registry, first) + assert.equal(registry.destroyEvents.size, 2) + destroyListeners(registry) + assert.equal(registry.destroyEvents.size, 1) + target.dispatchEvent(new Event('first')) + target.dispatchEvent(new Event('second')) + assert.deepEqual(calls, ['first']) + assert.deepEqual(warnings.map(item => item[1]), [failure, failure]) + denied = false + destroyListeners(registry) + assert.equal(registry.destroyEvents.size, 0) + target.dispatchEvent(new Event('first')) + assert.deepEqual(calls, ['first']) + scope.dispose() +}) + +test('manual destroy suppresses reentrant registrations but allows reuse until owner closes', () => { + const { registry, target, scope } = fixture() + const original = target.removeEventListener + let hits = 0 + target.removeEventListener = function (...args) { + destroyListeners(registry) + proxyListener(registry, target, 'reentrant', () => hits++) + original.apply(this, args) + } + proxyListener(registry, target, 'first', () => hits++) + destroyListeners(registry) + target.dispatchEvent(new Event('reentrant')) + assert.equal(hits, 0) + assert.equal(registry.destroyEvents.size, 0) + proxyListener(registry, target, 'next', () => hits++) + target.dispatchEvent(new Event('next')) + assert.equal(hits, 1) + scope.dispose() + proxyListener(registry, target, 'closed', () => hits++) + target.dispatchEvent(new Event('closed')) + assert.equal(hits, 1) + assert.equal(registry.destroyEvents.size, 0) +}) + +test('duplicate registrations preserve native callback deduplication without reference counting', () => { + const { registry, target, scope } = fixture() + let hits = 0 + const callback = () => hits++ + const first = proxyListener(registry, target, 'example', callback) + proxyListener(registry, target, 'example', callback) + target.dispatchEvent(new Event('example')) + assert.equal(hits, 1) + first() + target.dispatchEvent(new Event('example')) + assert.equal(hits, 1) + scope.dispose() + assert.equal(registry.destroyEvents.size, 0) +}) diff --git a/test/pointer-events.test.js b/test/pointer-events.test.js new file mode 100644 index 000000000..23f3d7e40 --- /dev/null +++ b/test/pointer-events.test.js @@ -0,0 +1,161 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { setImmediate } from 'node:timers/promises' +import { loadModules } from './helpers/load.js' + +const { clickInit, hoverInit, moveInit, Emitter, beginLifecycle, getScope } = await loadModules({ + clickInit: 'packages/artplayer/src/events/clickInit', + hoverInit: 'packages/artplayer/src/events/hoverInit', + moveInit: 'packages/artplayer/src/events/moveInit', + Emitter: 'packages/artplayer/src/utils/emitter', + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, +}) + +function fixture() { + const classes = new Set() + const $player = { classList: { add: name => classes.add(name), remove: name => classes.delete(name) } } + const $video = {} + const calls = [] + const callbacks = new Map() + const art = Object.assign(new Emitter(), { + template: { $player, $video }, + constructor: { DBCLICK_TIME: 300, DBCLICK_FULLSCREEN: true, MOBILE_CLICK_PLAY: false, MOBILE_DBCLICK_PLAY: true }, + isFocus: false, + isInput: false, + isLock: false, + fullscreen: false, + toggle: () => calls.push('toggle'), + }) + beginLifecycle(art) + const events = { + proxy(target, name, callback) { + callbacks.set(name, callback) + return () => callbacks.delete(name) + }, + hover(target, enter, leave) { + callbacks.set('mouseenter', enter) + callbacks.set('mouseleave', leave) + }, + } + clickInit(art, events) + hoverInit(art, events) + moveInit(art, events) + return { art, classes, calls, callbacks, dispose: () => getScope(art).dispose() } +} + +test('click grouping keeps the inclusive threshold, third-click reset and live settings', (t) => { + const f = fixture() + let now = 0 + t.mock.method(Date, 'now', () => now) + f.art.on('click', () => f.calls.push('click')) + f.art.on('dblclick', () => f.calls.push('dblclick')) + const click = f.callbacks.get('click') + click(new Event('click')) + now = 300 + click(new Event('click')) + assert.equal(f.art.fullscreen, true) + now = 301 + click(new Event('click')) + now = 602 + click(new Event('click')) + f.art.constructor.DBCLICK_FULLSCREEN = false + click(new Event('click')) + assert.equal(f.art.fullscreen, true) + assert.deepEqual(f.calls, ['click', 'toggle', 'dblclick', 'click', 'toggle', 'click', 'toggle', 'dblclick']) + f.dispose() +}) + +for (const name of ['click', 'dblclick']) { + test(`destruction during ${name} stops the remaining playback or fullscreen action`, () => { + const f = fixture() + f.art.constructor.DBCLICK_TIME = 60000 + f.art.on(name, f.dispose) + f.callbacks.get('click')(new Event('click')) + if (name === 'dblclick') + f.callbacks.get('click')(new Event('click')) + assert.equal(f.art.fullscreen, false) + assert.deepEqual(f.calls, name === 'click' ? [] : ['toggle']) + f.callbacks.get('click')(new Event('click')) + assert.deepEqual(f.calls, name === 'click' ? [] : ['toggle']) + }) +} + +test('click callback errors retain identity and stop the default action', () => { + const f = fixture() + const failure = new Error('caller failed') + const callback = () => { + throw failure + } + f.art.on('click', callback) + assert.throws(() => f.callbacks.get('click')(new Event('click')), error => error === failure) + assert.deepEqual(f.calls, []) + f.dispose() +}) + +test('click-triggered playback rejection remains handled internally', async () => { + const f = fixture() + f.art.toggle = () => Promise.reject(new DOMException('interrupted', 'AbortError')) + f.callbacks.get('click')(new Event('click')) + await setImmediate() + f.dispose() +}) + +test('nested clicks preserve the historical synchronous grouping and event identity', (t) => { + const f = fixture() + t.mock.method(Date, 'now', () => 100) + const first = new Event('click') + const nested = new Event('click') + f.art.on('click', (event) => { + assert.equal(event, first) + f.calls.push('click') + f.callbacks.get('click')(nested) + }) + f.art.on('dblclick', event => f.calls.push(event === nested ? 'nested' : 'next')) + f.callbacks.get('click')(first) + assert.equal(f.art.fullscreen, true) + f.callbacks.get('click')(new Event('click')) + assert.equal(f.art.fullscreen, false) + assert.deepEqual(f.calls, ['click', 'nested', 'toggle', 'next']) + f.dispose() +}) + +test('focus flags retain input-only semantics and disposal removes only owned subscriptions', () => { + const f = fixture() + const events = [] + f.art.on('focus', event => events.push(event)) + const input = { tagName: 'INPUT' } + const event = { target: input, composedPath: () => [input, f.art.template.$player] } + f.art.emit('document:click', event) + assert.equal(f.art.isInput, true) + assert.equal(f.art.isFocus, true) + assert.equal(events[0], event) + input.tagName = 'TEXTAREA' + f.art.emit('document:contextmenu', event) + assert.equal(f.art.isInput, false) + let external = 0 + f.art.on('document:click', () => external++) + f.dispose() + f.art.emit('document:click', { target: null, composedPath: () => [] }) + assert.equal(f.art.isFocus, true) + assert.equal(external, 1) + assert.equal(events.length, 2) +}) + +test('hover and move preserve class-before-event ordering and reject stale callbacks', () => { + const f = fixture() + const states = [] + const event = new Event('mousemove') + f.art.on('hover', (state, original) => states.push([state, original, f.classes.has('art-hover')])) + f.art.on('mousemove', original => states.push(['move', original])) + f.callbacks.get('mouseenter')(event) + f.callbacks.get('mousemove')(event) + f.callbacks.get('mouseleave')(event) + assert.deepEqual(states, [[true, event, true], ['move', event], [false, event, false]]) + f.dispose() + f.callbacks.get('mouseenter')(event) + f.callbacks.get('mousemove')(event) + assert.equal(f.classes.size, 0) + assert.equal(states.length, 3) +}) diff --git a/test/types/events-source.ts b/test/types/events-source.ts new file mode 100644 index 000000000..75fe9e3a9 --- /dev/null +++ b/test/types/events-source.ts @@ -0,0 +1,29 @@ +import type { GlobalEventSource } from '../../packages/artplayer/src/events/global-types' +import type { ViewEvents, ViewHost } from '../../packages/artplayer/src/events/scheduling-types' +import type { EventsHost } from '../../packages/artplayer/src/events/types' +import Events from '../../packages/artplayer/src/events' +import { eventSubscriptions } from '../../packages/artplayer/src/events/subscriptions' + +declare const host: EventsHost +declare const view: ViewHost +declare const source: GlobalEventSource +const events = new Events(host) +const target = document.createElement('button') +const dispose: () => void = events.proxy(target, 'click', event => event.preventDefault(), null) +const disposers: (() => void)[] = events.proxy(target, ['click', 'mouseenter'], { handleEvent: event => event.preventDefault() }) +events.remove(dispose) +disposers.forEach(remove => remove()) +events.bindGlobalEvents(source) +// @ts-expect-error Native registration requires a string name or array. +events.proxy(target, 123, () => {}) +// @ts-expect-error Public hover supplies an Event, not a narrower keyboard event. +events.hover(target, (event: KeyboardEvent) => event.code) +const on = eventSubscriptions(view) +on('view', (visible) => { + const value: boolean = visible + return value +}) +// @ts-expect-error View payloads are boolean. +on('view', (visible: string) => visible) +// @ts-expect-error The subscription factory only accepts its declared event map. +on('resize', () => {}) diff --git a/test/types/gesture.ts b/test/types/gesture.ts new file mode 100644 index 000000000..95bf673b2 --- /dev/null +++ b/test/types/gesture.ts @@ -0,0 +1,16 @@ +import type { GestureHost } from '../../packages/artplayer/src/input/gesture-types' +import type Artplayer from '../../packages/artplayer/types/artplayer' +import { gestureController } from '../../packages/artplayer/src/input/gesture-controller' + +declare const art: Artplayer +declare const host: GestureHost +const gesture = gestureController(host) +gesture.start(host.template.$video, new TouchEvent('touchstart')) +gesture.move(new TouchEvent('touchmove')) +gesture.cancel() +// @ts-expect-error Gesture input requires touch coordinates and identifiers. +gesture.move(new MouseEvent('mousemove')) +art.on('document:touchcancel', (event) => { + const original: Event = event + return original +}) diff --git a/test/types/hotkey.ts b/test/types/hotkey.ts new file mode 100644 index 000000000..242a5ebc0 --- /dev/null +++ b/test/types/hotkey.ts @@ -0,0 +1,18 @@ +import type { HotkeyHost } from '../../packages/artplayer/src/input/hotkey-types' +import Hotkey from '../../packages/artplayer/src/hotkey' + +declare const host: HotkeyHost & { extension: string } +const keys = new Hotkey(host) +keys.add('KeyK', function (event) { + const extension: string = this.extension + const code: string = event.code + return { extension, code } +}).remove('KeyK', () => {}) +const same: typeof host = keys.art +// @ts-expect-error Keyboard callbacks receive a keyboard event. +keys.add('KeyK', (event: MouseEvent) => event.clientX) +// @ts-expect-error The callback receiver preserves the host extension type. +keys.add('KeyK', function (this: { extension: number }) { + return this.extension +}) +export { same }