From 73f0ca3ae4f163be410328a1821279569e573cb7 Mon Sep 17 00:00:00 2001 From: Toil <62353659+ilyhalight@users.noreply.github.com> Date: Tue, 29 Oct 2024 15:49:19 +0300 Subject: [PATCH] fix translation button on change video with old player --- bun.lockb | Bin 391882 -> 391882 bytes changelog.md | 6 +++++- dist/vot-min.user.js | 8 ++++---- dist/vot.user.js | 27 ++++++++++++++++++++------- package.json | 2 +- src/headers.json | 2 +- src/index.js | 13 ++++++++++--- 7 files changed, 41 insertions(+), 17 deletions(-) diff --git a/bun.lockb b/bun.lockb index 1f736f2847012dd50b97eef7c28602f603392be0..c466ca4717aa10d9b89d57f4b71e5fe94a9b72c2 100644 GIT binary patch delta 157 zcmV;O0Al~j^%u(Z7mzL>urWO)A6cXu}(TZ zlgKQJ2g-7ALf^Nftw zEp^tVZbg2!)QQL(Kw5>=;x+OSNv;7TyA+4LX90)3X9BmqX9F~Y0Wr7o>H{<00Wyas L$pp71$pxe_GKxvN delta 157 zcmV;O0Al~j^%u(Z7mzL>h+4YiE~H8ax}&Ie&D_OXpJa0}@=X{t#1As`ygIEDu}(TZ zlSo7`gSbAoxIO{JC_uK=n=6VOM4{BV;u!ArMe!F!apM%-X79@z`1_ymG!_k5mS1Mr zRh7VIYJ8pxthw&yM$(a9fBR0C8-LtW#r}uAX90)3X9BmqX9F~Y0Wi1n>H{<00WpUr L$pp71$pxe_9rsM+ diff --git a/changelog.md b/changelog.md index 9ce9a5e1..5e6406d6 100644 --- a/changelog.md +++ b/changelog.md @@ -26,9 +26,13 @@ - (ПРОВЕРИТЬ ЕЩЕ РАЗ) Исправлена ошибка из-за которой озвучка иногда могла не стартовать со старым плеером (#840) +# 1.7.1 Beta 4 + +- Исправлена ошибка из-за которой при смене видео кнопка могла перестать работать со старым плеером ([875#discussioncomment-11085577](https://github.com/ilyhalight/voice-over-translation/discussions/875#discussioncomment-11085577)) + # 1.7.1 Beta 3 -- Обновлена логика запросов к VOT Worker для поддержки новых запросов из 1.7.1 Beta 2 +- Обновлена логика запросов к VOT Worker для поддержки новых запросов из 1.7.1-beta2 - Обновлена логика нового плеера. Теперь, он не использует Tone.js и работает лучше, чем раньше # 1.7.1 Beta 2 diff --git a/dist/vot-min.user.js b/dist/vot-min.user.js index bb7ba371..08fdd343 100644 --- a/dist/vot-min.user.js +++ b/dist/vot-min.user.js @@ -165,7 +165,7 @@ // @connect onrender.com // @connect workers.dev // @namespace vot-min -// @version 1.7.1-beta3 +// @version 1.7.1-beta4 // @icon https://translate.yandex.ru/icons/favicon.ico // @author sodapng, mynovelhost, Toil, SashaXser, MrSoczekXD // @homepageURL https://github.com/ilyhalight/voice-over-translation @@ -245,7 +245,7 @@ - `,c);const h=He(n,r,s,{onSelectCb:l});return d.append(u.container,c,h.container),{container:d,fromSelect:u,icon:c,toSelect:h}},updateSlider:Fe,animateLoader:function(t,e="139, 180, 245"){const o=t.querySelector(".vot-loader-helper"),i=t.querySelector(".vot-loader-main");anime.timeline({...$e,targets:[o,i],duration:250}).add({"fill-opacity":0,"stroke-width":2,d:"M 12 1.5 C 17.799 1.5 22.5 6.201 22.5 12 C 22.5 17.799 17.799 22.5 12 22.5 C 6.201 22.5 1.5 17.799 1.5 12 C 1.5 6.201 6.201 1.5 12 1.5 Z",duration:0}).add({targets:o,stroke:`rgb(${e})`,"stroke-opacity":0,duration:0},0).add({targets:i,stroke:"#888888","stroke-opacity":.25},0);const a=anime.timeline({targets:o,easing:"easeInOutSine",duration:1e3,autoplay:!1}).add({strokeOpacity:1,duration:0},0).add({strokeDashoffset:[anime.setDashoffset,0]},0);return t=>{a.seek(a.duration*(t/100))}},afterAnimateLoader:function(t,e="139, 180, 245"){const o=t.querySelector(".vot-loader-helper"),i=t.querySelector(".vot-loader-main");anime.timeline({...$e,targets:i,duration:600}).add({d:"M 9.0596 14.8571 L 9.7667 15.5642 L 10.4738 14.8571 L 17.0071 8.3238 C 17.0457 8.2852 17.0937 8.25 17.2333 8.25 C 17.373 8.25 17.421 8.2852 17.4596 8.3238 C 17.4981 8.3624 17.5333 8.4104 17.5333 8.55 C 17.5333 8.6896 17.4981 8.7376 17.4596 8.7762 L 9.9929 16.2429 C 9.9011 16.3346 9.8397 16.35 9.7667 16.35 C 9.6937 16.35 9.6322 16.3346 9.5404 16.2429 L 6.0738 12.7762 C 6.0352 12.7376 6 12.6897 6 12.55 C 6 12.4103 6.0352 12.3624 6.0738 12.3238 C 6.1124 12.2852 6.1603 12.25 6.3 12.25 C 6.4397 12.25 6.4876 12.2852 6.5262 12.3238 L 9.0596 14.8571 Z",duration:0}).add({strokeDashoffset:[anime.setDashoffset,0],stroke:`rgb(${e})`,"stroke-opacity":1}),setTimeout((()=>{anime.timeline({...$e,targets:i,duration:600}).add({d:"M12 15.575C11.8667 15.575 11.7417 15.5542 11.625 15.5125C11.5083 15.4708 11.4 15.4 11.3 15.3L7.7 11.7C7.5 11.5 7.40417 11.2667 7.4125 11C7.42083 10.7333 7.51667 10.5 7.7 10.3C7.9 10.1 8.1375 9.99583 8.4125 9.9875C8.6875 9.97917 8.925 10.075 9.125 10.275L11 12.15V5C11 4.71667 11.0958 4.47917 11.2875 4.2875C11.4792 4.09583 11.7167 4 12 4C12.2833 4 12.5208 4.09583 12.7125 4.2875C12.9042 4.47917 13 4.71667 13 5V12.15L14.875 10.275C15.075 10.075 15.3125 9.97917 15.5875 9.9875C15.8625 9.99583 16.1 10.1 16.3 10.3C16.4833 10.5 16.5792 10.7333 16.5875 11C16.5958 11.2667 16.5 11.5 16.3 11.7L12.7 15.3C12.6 15.4 12.4917 15.4708 12.375 15.5125C12.2583 15.5542 12.1333 15.575 12 15.575ZM6 20C5.45 20 4.97917 19.8042 4.5875 19.4125C4.19583 19.0208 4 18.55 4 18V16C4 15.7167 4.09583 15.4792 4.2875 15.2875C4.47917 15.0958 4.71667 15 5 15C5.28333 15 5.52083 15.0958 5.7125 15.2875C5.90417 15.4792 6 15.7167 6 16V18H18V16C18 15.7167 18.0958 15.4792 18.2875 15.2875C18.4792 15.0958 18.7167 15 19 15C19.2833 15 19.5208 15.0958 19.7125 15.2875C19.9042 15.4792 20 15.7167 20 16V18C20 18.55 19.8042 19.0208 19.4125 19.4125C19.0208 19.8042 18.55 20 18 20H6Z",duration:100}).add({targets:o,d:"",duration:200},0).add({targets:i,"stroke-width":"0",stroke:`rgba(${e}), 0)`,"fill-opacity":"1","stroke-dasharray":"0","stroke-dashoffset":"0",duration:0})}),2e3)},createDetails:function(t){const e=document.createElement("vot-block");e.classList.add("vot-details");const o=document.createElement("vot-block");o.append(t);const i=document.createElement("vot-block");return i.classList.add("vot-details-arrow-icon"),ue(Re,i),e.append(o,i),{container:e,header:o,arrowIcon:i}}};o("./node_modules/requestidlecallback-polyfill/index.js");class We{constructor(){this.listeners=new Set}hasListener(t){return this.listeners.has(t)}dispatchToListener(t,...e){try{t(...e)}catch(t){console.error("[VOT]",t)}}addListener(t){if(this.hasListener(t))throw new Error("[VOT] The listener has already been added.");this.listeners.add(t)}removeListener(t){if(!this.hasListener(t))throw new Error("[VOT] The listener has not been added yet.");this.listeners.delete(t)}dispatch(...t){for(const e of Array.from(this.listeners))this.dispatchToListener(e,...t)}}const je=new Set(["advertise","promo","sponsor","banner","commercial","preroll","midroll","postroll","ad-container","sponsored"]),Ge=(()=>{const t=Array.from(je).join("|");return new RegExp(t,"i")})(),Ye=t=>{const e=[];for(let o=0;o=0||(o=(t.length-i)/2);const a=2*o;this.ensureCapacity(o+this._frameCount);const n=this.endIndex;this.vector.set(t.subarray(i,i+a),n),this._frameCount+=o}putBuffer(t,e,o=0){e=e||0,o>=0||(o=t.frameCount-e),this.putSamples(t.vector,t.position+e,o)}receive(t){t>=0&&!(t>this._frameCount)||(t=this.frameCount),this._frameCount-=t,this._position+=t}receiveSamples(t,e=0){const o=2*e,i=this.startIndex;t.set(this._vector.subarray(i,i+o)),this.receive(e)}extract(t,e=0,o=0){const i=this.startIndex+2*e,a=2*o;t.set(this._vector.subarray(i,i+a))}ensureCapacity(t=0){const e=parseInt(2*t);if(this._vector.length0&&(this._vector.set(this._vector.subarray(this.startIndex,this.endIndex)),this._position=0)}}class Ze{constructor(t){t?(this._inputBuffer=new Ke,this._outputBuffer=new Ke):this._inputBuffer=this._outputBuffer=null}get inputBuffer(){return this._inputBuffer}set inputBuffer(t){this._inputBuffer=t}get outputBuffer(){return this._outputBuffer}set outputBuffer(t){this._outputBuffer=t}clear(){this._inputBuffer.clear(),this._outputBuffer.clear()}}class Xe extends Ze{constructor(t){super(t),this.reset(),this._rate=1}set rate(t){this._rate=t}reset(){this.slopeCount=0,this.prevSampleL=0,this.prevSampleR=0}clone(){const t=new Xe;return t.rate=this._rate,t}process(){const t=this._inputBuffer.frameCount;this._outputBuffer.ensureAdditionalCapacity(t/this._rate+1);const e=this.transpose(t);this._inputBuffer.receive(),this._outputBuffer.put(e)}transpose(t=0){if(0===t)return 0;const e=this._inputBuffer.vector,o=this._inputBuffer.startIndex,i=this._outputBuffer.vector,a=this._outputBuffer.endIndex;let n=0,r=0;for(;this.slopeCount<1;)i[a+2*r]=(1-this.slopeCount)*this.prevSampleL+this.slopeCount*e[o],i[a+2*r+1]=(1-this.slopeCount)*this.prevSampleR+this.slopeCount*e[o+1],r+=1,this.slopeCount+=this._rate;if(this.slopeCount-=1,1!==t)t:for(;;){for(;this.slopeCount>1;)if(this.slopeCount-=1,n+=1,n>=t-1)break t;const s=o+2*n;i[a+2*r]=(1-this.slopeCount)*e[s]+this.slopeCount*e[s+2],i[a+2*r+1]=(1-this.slopeCount)*e[s+1]+this.slopeCount*e[s+3],r+=1,this.slopeCount+=this._rate}return this.prevSampleL=e[o+2*t-2],this.prevSampleR=e[o+2*t-1],r}}class Qe{constructor(t){this._pipe=t}get pipe(){return this._pipe}get inputBuffer(){return this._pipe.inputBuffer}get outputBuffer(){return this._pipe.outputBuffer}fillInputBuffer(){throw new Error("fillInputBuffer() not overridden")}fillOutputBuffer(t=0){for(;this.outputBuffer.frameCountthis._position)throw new RangeError("New position may not be greater than current position");const e=this.outputBufferPosition-(this._position-t);if(e<0)throw new RangeError("New position falls outside of history buffer");this.outputBufferPosition=e,this._position=t}get sourcePosition(){return this._sourcePosition}set sourcePosition(t){this.clear(),this._sourcePosition=t}onEnd(){this.callback()}fillInputBuffer(t=0){const e=new Float32Array(2*t),o=this.sourceSound.extract(e,t,this._sourcePosition);this._sourcePosition+=o,this.inputBuffer.putSamples(e,0,o)}extract(t,e=0){this.fillOutputBuffer(this.outputBufferPosition+e);const o=Math.min(e,this.outputBuffer.frameCount-this.outputBufferPosition);this.outputBuffer.extract(t,this.outputBufferPosition,o);const i=this.outputBufferPosition+o;return this.outputBufferPosition=Math.min(this.historyBufferSize,i),this.outputBuffer.receive(Math.max(i-this.historyBufferSize,0)),this._position+=o,o}handleSampleData(t){this.extract(t.data,4096)}clear(){super.clear(),this.outputBufferPosition=0}}const oo=[[124,186,248,310,372,434,496,558,620,682,744,806,868,930,992,1054,1116,1178,1240,1302,1364,1426,1488,0],[-100,-75,-50,-25,25,50,75,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[-20,-15,-10,-5,5,10,15,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[-4,-3,-2,-1,1,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],io=-10/1.5;class ao extends Ze{constructor(t){super(t),this._quickSeek=!0,this.midBufferDirty=!1,this.midBuffer=null,this.overlapLength=0,this.autoSeqSetting=!0,this.autoSeekSetting=!0,this._tempo=1,this.setParameters(44100,0,0,8)}clear(){super.clear(),this.clearMidBuffer()}clearMidBuffer(){this.midBufferDirty&&(this.midBufferDirty=!1,this.midBuffer=null)}setParameters(t,e,o,i){t>0&&(this.sampleRate=t),i>0&&(this.overlapMs=i),e>0?(this.sequenceMs=e,this.autoSeqSetting=!1):this.autoSeqSetting=!0,o>0?(this.seekWindowMs=o,this.autoSeekSetting=!1):this.autoSeekSetting=!0,this.calculateSequenceParameters(),this.calculateOverlapLength(this.overlapMs),this.tempo=this._tempo}set tempo(t){let e;this._tempo=t,this.calculateSequenceParameters(),this.nominalSkip=this._tempo*(this.seekWindowLength-this.overlapLength),this.skipFract=0,e=Math.floor(this.nominalSkip+.5),this.sampleReq=Math.max(e+this.overlapLength,this.seekWindowLength)+this.seekLength}get tempo(){return this._tempo}get inputChunkSize(){return this.sampleReq}get outputChunkSize(){return this.overlapLength+Math.max(0,this.seekWindowLength-2*this.overlapLength)}calculateOverlapLength(t=0){let e;e=this.sampleRate*t/1e3,e=e<16?16:e,e-=e%8,this.overlapLength=e,this.refMidBuffer=new Float32Array(2*this.overlapLength),this.midBuffer=new Float32Array(2*this.overlapLength)}checkLimits(t,e,o){return to?o:t}calculateSequenceParameters(){let t,e;this.autoSeqSetting&&(t=150+-50*this._tempo,t=this.checkLimits(t,50,125),this.sequenceMs=Math.floor(t+.5)),this.autoSeekSetting&&(e=28.333333333333332+io*this._tempo,e=this.checkLimits(e,15,25),this.seekWindowMs=Math.floor(e+.5)),this.seekWindowLength=Math.floor(this.sampleRate*this.sequenceMs/1e3),this.seekLength=Math.floor(this.sampleRate*this.seekWindowMs/1e3)}set quickSeek(t){this._quickSeek=t}clone(){const t=new ao;return t.tempo=this._tempo,t.setParameters(this.sampleRate,this.sequenceMs,this.seekWindowMs,this.overlapMs),t}seekBestOverlapPosition(){return this._quickSeek?this.seekBestOverlapPositionStereoQuick():this.seekBestOverlapPositionStereo()}seekBestOverlapPositionStereo(){let t,e,o,i=0;for(this.preCalculateCorrelationReferenceStereo(),t=0,e=Number.MIN_VALUE;ie&&(e=o,t=i);return t}seekBestOverlapPositionStereoQuick(){let t,e,o,i,a,n=0;for(this.preCalculateCorrelationReferenceStereo(),e=Number.MIN_VALUE,t=0,i=0,a=0;n<4;n+=1){let r=0;for(;oo[n][r]&&(a=i+oo[n][r],!(a>=this.seekLength));)o=this.calculateCrossCorrelationStereo(2*a,this.refMidBuffer),o>e&&(e=o,t=a),r+=1;i=t}return t}preCalculateCorrelationReferenceStereo(){let t,e,o=0;for(;o=this.sampleReq;){t=this.seekBestOverlapPosition(),this._outputBuffer.ensureAdditionalCapacity(this.overlapLength),this.overlap(Math.floor(t)),this._outputBuffer.put(this.overlapLength),e=this.seekWindowLength-2*this.overlapLength,e>0&&this._outputBuffer.putBuffer(this._inputBuffer,t+this.overlapLength,e);const i=this._inputBuffer.startIndex+2*(t+this.seekWindowLength-this.overlapLength);this.midBuffer.set(this._inputBuffer.vector.subarray(i,i+2*this.overlapLength)),this.skipFract+=this.nominalSkip,o=Math.floor(this.skipFract),this.skipFract-=o,this._inputBuffer.receive(o)}}}const no=function(t,e){return(t>e?t-e:e-t)>1e-10};class ro{constructor(){this.transposer=new Xe(!1),this.stretch=new ao(!1),this._inputBuffer=new Ke,this._intermediateBuffer=new Ke,this._outputBuffer=new Ke,this._rate=0,this._tempo=0,this.virtualPitch=1,this.virtualRate=1,this.virtualTempo=1,this.calculateEffectiveRateAndTempo()}clear(){this.transposer.clear(),this.stretch.clear()}clone(){const t=new ro;return t.rate=this.rate,t.tempo=this.tempo,t}get rate(){return this._rate}set rate(t){this.virtualRate=t,this.calculateEffectiveRateAndTempo()}set rateChange(t){this._rate=1+.01*t}get tempo(){return this._tempo}set tempo(t){this.virtualTempo=t,this.calculateEffectiveRateAndTempo()}set tempoChange(t){this.tempo=1+.01*t}set pitch(t){this.virtualPitch=t,this.calculateEffectiveRateAndTempo()}set pitchOctaves(t){this.pitch=Math.exp(.69314718056*t),this.calculateEffectiveRateAndTempo()}set pitchSemitones(t){this.pitchOctaves=t/12}get inputBuffer(){return this._inputBuffer}get outputBuffer(){return this._outputBuffer}calculateEffectiveRateAndTempo(){const t=this._tempo,e=this._rate;this._tempo=this.virtualTempo/this.virtualPitch,this._rate=this.virtualRate*this.virtualPitch,no(this._tempo,t)&&(this.stretch.tempo=this._tempo),no(this._rate,e)&&(this.transposer.rate=this._rate),this._rate>1?this._outputBuffer!=this.transposer.outputBuffer&&(this.stretch.inputBuffer=this._inputBuffer,this.stretch.outputBuffer=this._intermediateBuffer,this.transposer.inputBuffer=this._intermediateBuffer,this.transposer.outputBuffer=this._outputBuffer):this._outputBuffer!=this.stretch.outputBuffer&&(this.transposer.inputBuffer=this._inputBuffer,this.transposer.outputBuffer=this._intermediateBuffer,this.stretch.inputBuffer=this._intermediateBuffer,this.stretch.outputBuffer=this._outputBuffer)}process(){this._rate>1?(this.stretch.process(),this.transposer.process()):(this.transposer.process(),this.stretch.process())}}class so{constructor(t){this.buffer=t,this._position=0}get dualChannel(){return this.buffer.numberOfChannels>1}get position(){return this._position}set position(t){this._position=t}extract(t,e=0,o=0){this.position=o;let i=this.buffer.getChannelData(0),a=this.dualChannel?this.buffer.getChannelData(1):this.buffer.getChannelData(0),n=0;for(;n=e?t:new Array(e-t.length+1).join(o)+t}(parseInt(t-60*e),2)}`},uo=function(t){const e=this.timePlayed,o=this.sampleRate;if(this.sourcePosition=t,this.timePlayed=t/o,e!==this.timePlayed){const t=new CustomEvent("play",{detail:{timePlayed:this.timePlayed,formattedTimePlayed:this.formattedTimePlayed,percentagePlayed:this.percentagePlayed}});this._node.dispatchEvent(t)}};class co{constructor(t,e,o,i=to){this._soundtouch=new ro;const a=new so(e);this.timePlayed=0,this.sourcePosition=0,this._filter=new eo(a,this._soundtouch,i),this._node=function(t,e,o=to,i=4096){const a=t.createScriptProcessor(i,2,2),n=new Float32Array(2*i);return a.onaudioprocess=t=>{let a=t.outputBuffer.getChannelData(0),r=t.outputBuffer.getChannelData(1),s=e.extract(n,i);o(e.sourcePosition),0===s&&e.onEnd();let l=0;for(;luo.call(this,t)),o),this.tempo=1,this.rate=1,this.duration=e.duration,this.sampleRate=t.sampleRate,this.listeners=[]}get formattedDuration(){return lo(this.duration)}get formattedTimePlayed(){return lo(this.timePlayed)}get percentagePlayed(){return 100*this._filter.sourcePosition/(this.duration*this.sampleRate)}set percentagePlayed(t){this._filter.sourcePosition=parseInt(t*this.duration*this.sampleRate),this.sourcePosition=this._filter.sourcePosition,this.timePlayed=this.sourcePosition/this.sampleRate}get node(){return this._node}set pitch(t){this._soundtouch.pitch=t}set pitchSemitones(t){this._soundtouch.pitchSemitones=t}set rate(t){this._soundtouch.rate=t}set tempo(t){this._soundtouch.tempo=t}connect(t){this._node.connect(t)}disconnect(){this._node.disconnect()}on(t,e){this.listeners.push({name:t,cb:e}),this._node.addEventListener(t,(t=>e(t.detail)))}off(t=null){let e=this.listeners;t&&(e=e.filter((e=>e.name===t))),e.forEach((t=>{this._node.removeEventListener(t.name,(e=>t.cb(e.detail)))}))}}const ho=(...t)=>{if(Je.debug)return console.log(`%c✦ chaimu.js v${Je.version} ✦`,"background: #000; color: #fff; padding: 0 8px",...t)},po=["playing","ratechange","play","waiting","pause","seeked"];function go(){const t=window.AudioContext||window.webkitAudioContext;return t?new t:void 0}class mo{static name="BasePlayer";chaimu;_src;fetch;constructor(t,e){this.chaimu=t,this._src=e,this.fetch=Je.fetchFn}async init(){return new Promise((t=>t(this)))}clear(){return new Promise((t=>t(this)))}lipSync(t=!1){return this}handleVideoEvent=t=>(ho(`handle video ${t.type}`),this.lipSync(t.type),this);removeVideoEvents(){for(const t of po)this.chaimu.video.removeEventListener(t,this.handleVideoEvent);return this}addVideoEvents(){for(const t of po)this.chaimu.video.addEventListener(t,this.handleVideoEvent);return this}async play(){return new Promise((t=>t(this)))}async pause(){return new Promise((t=>t(this)))}get name(){return this.constructor.name}set src(t){this._src=t}get src(){return this._src}get currentSrc(){return this._src}set volume(t){}get volume(){return 0}get playbackRate(){return 0}set playbackRate(t){}get currentTime(){return 0}}class vo extends mo{static name="AudioPlayer";audio;gainNode;audioSource;constructor(t,e){super(t,e),this.audio=new Audio(e),this.audio.crossOrigin="anonymous"}initAudioBooster(){return this.chaimu.audioContext?(this.gainNode&&this.audioSource&&(this.audioSource.disconnect(this.gainNode),this.gainNode.disconnect()),this.gainNode=this.chaimu.audioContext.createGain(),this.gainNode.connect(this.chaimu.audioContext.destination),this.audioSource=this.chaimu.audioContext.createMediaElementSource(this.audio),this.audioSource.connect(this.gainNode),this):this}async init(){return new Promise((t=>(this.initAudioBooster(),t(this))))}audioErrorHandle=t=>{console.error("[AudioPlayer]",t)};lipSync(t=!1){if(ho("[AudioPlayer] lipsync video",this.chaimu.video),!this.chaimu.video)return this;if(this.audio.currentTime=this.chaimu.video.currentTime,this.audio.playbackRate=this.chaimu.video.playbackRate,!t)return ho("[AudioPlayer] lipsync mode isn't set"),this;switch(ho(`[AudioPlayer] lipsync mode is ${t}`),t){case"play":case"playing":case"seeked":return this.chaimu.video.paused||this.syncPlay(),this;case"pause":case"waiting":return this.pause(),this;default:return this}}async clear(){return new Promise((t=>(this.audio.pause(),this.audio.src="",this.audio.removeAttribute("src"),t(this))))}syncPlay(){return ho("[AudioPlayer] sync play called"),this.audio.play().catch(this.audioErrorHandle),this}async play(){return ho("[AudioPlayer] play called"),await this.audio.play().catch(this.audioErrorHandle),this}async pause(){return new Promise((t=>(ho("[AudioPlayer] pause called"),this.audio.pause(),t(this))))}set src(t){this.audio.src=t}get src(){return this.audio.src}get currentSrc(){return this.audio.currentSrc}set volume(t){this.gainNode?this.gainNode.gain.value=t:this.audio.volume=t}get volume(){return this.gainNode?this.gainNode.gain.value:this.audio.volume}get playbackRate(){return this.audio.playbackRate}set playbackRate(t){this.audio.playbackRate=t}get currentTime(){return this.audio.currentTime}}class fo extends mo{static name="ChaimuPlayer";audioBuffer;sourceNode;gainNode;audioShifter;cleanerRunned=!1;async fetchAudio(){if(!this._src)throw new Error("No audio source provided");if(!this.chaimu.audioContext)throw new Error("No audio context available");ho(`[ChaimuPlayer] Fetching audio from ${this._src}...`);try{const t=await this.fetch(this._src);ho("[ChaimuPlayer] Decoding fetched audio...");const e=await t.arrayBuffer();this.audioBuffer=await this.chaimu.audioContext.decodeAudioData(e)}catch(t){throw new Error(`Failed to fetch audio file, because ${t.message}`)}return this}initAudioBooster(){return this.chaimu.audioContext?(this.gainNode&&this.gainNode.disconnect(),this.gainNode=this.chaimu.audioContext.createGain(),this):this}async init(){return await this.fetchAudio(),this.initAudioBooster(),this}lipSync(t=!1){if(ho("[ChaimuPlayer] lipsync video",this.chaimu.video,this),!this.chaimu.video)return this;if(!t)return ho("[ChaimuPlayer] lipsync mode isn't set"),this;switch(ho(`[ChaimuPlayer] lipsync mode is ${t}`),t){case"play":case"playing":case"ratechange":case"seeked":return this.chaimu.video.paused||this.start(),this;case"pause":case"waiting":return this.pause(),this;default:return this}}async reopenCtx(){if(!this.chaimu.audioContext)throw new Error("No audio context available");try{await this.chaimu.audioContext.close()}catch{}return this}async clear(){if(!this.chaimu.audioContext)throw new Error("No audio context available");if(ho("clear audio context"),this.cleanerRunned=!0,await this.pause(),!this.gainNode)return this.cleanerRunned=!1,this;this.sourceNode&&(this.sourceNode.stop(),this.sourceNode.disconnect(this.gainNode),this.sourceNode=void 0),this.audioShifter&&(this.audioShifter._node.disconnect(this.gainNode),this.audioShifter=void 0),this.gainNode.disconnect();const t=this.volume;return this.gainNode=void 0,await this.reopenCtx(),this.chaimu.audioContext=go(),this.initAudioBooster(),this.volume=t,this.cleanerRunned=!1,this}async start(){if(!this.chaimu.audioContext)throw new Error("No audio context available");if(!this.audioBuffer)throw new Error("The player isn't initialized");return!this.gainNode||this.audioShifter&&this.audioShifter.duration({label:J.get("langs")[t]??t.toUpperCase(),value:t,selected:e===t})))}const xo=t=>t?J.get("VOTChangeHotkeyWithCurrent").replace("{0}",t.replace("Key","")):J.get("VOTCreateTranslationHotkey");class So{translateFromLang="en";translateToLang=Z;timer;videoData="";firstPlay=!0;audioContext=go();hls=Q();votClient;audioPlayer;videoTranslations=[];videoTranslationTTL=7200;cachedTranslation;downloadTranslationUrl=null;autoRetry;streamPing;votOpts;volumeOnStart;tempOriginalVolume;tempVolume;firstSyncVolume=!0;subtitlesList=[];subtitlesListVideoId=null;dragging;constructor(t,e,o){N.log("[VideoHandler] add video:",t,"container:",e,this),this.video=t,this.container=e,this.site=o,this.init()}async translateVideoImpl(t,e,o,i=null){if(clearTimeout(this.autoRetry),N.log(t,`Translate video (requestLang: ${e}, responseLang: ${o})`),await pt(this.site,this.video)!==t.videoId)return null;try{const a=await this.votClient.translateVideo({videoData:t,requestLang:e,responseLang:o,translationHelp:i});if(N.log("Translate video result",a),a.translated&&a.remainingTime<1)return N.log("Video translation finished with this data: ",a),a;await this.updateTranslationErrorMsg(a.remainingTime>0?function(t){const e=Math.floor(t/60),o=Math.floor(t%60);return e>=60?J.get("translationTakeMoreThanHour"):1===e||0===e&&o>0?J.get("translationTakeAboutMinute"):11!==e&&e%10==1?J.get("translationTakeApproximatelyMinute2").replace("{0}",e):![12,13,14].includes(e)&&[2,3,4].includes(e%10)?J.get("translationTakeApproximatelyMinute").replace("{0}",e):J.get("translationTakeApproximatelyMinutes").replace("{0}",e)}(a.remainingTime):a.message??J.get("translationTakeFewMinutes"))}catch(t){return console.error("[VOT] Failed to translate video",t),await this.updateTranslationErrorMsg(t.data?.message??t),null}return new Promise((a=>{const n=this.subtitlesList.some((t=>"yandex"===t.source))?2e4:3e4;this.autoRetry=setTimeout((async()=>{const n=await this.translateVideoImpl(t,e,o,i);(!n||n.translated&&n.remainingTime<1)&&a(n)}),n)}))}async translateStreamImpl(t,e,o){if(clearTimeout(this.autoRetry),N.log(t,`Translate stream (requestLang: ${e}, responseLang: ${o})`),await pt(this.site,this.video)!==t.videoId)return null;try{const i=await this.votClient.translateStream({videoData:t,requestLang:e,responseLang:o});if(N.log("Translate stream result",i),!i.translated&&10===i.interval)return await this.updateTranslationErrorMsg(J.get("translationTakeFewMinutes")),new Promise((a=>{this.autoRetry=setTimeout((async()=>{const i=await this.translateStreamImpl(t,e,o);i&&!i.translated&&10===i.interval||a(i)}),1e3*i.interval)}));if(i.message)throw N.log(`Stream translation aborted! Message: ${i.message}`),new mt("streamNoConnectionToServer");if(!i.result)throw N.log("Failed to find translation result! Data:",i),new mt("audioNotReceived");return N.log("Stream translated successfully. Running...",i),this.streamPing=setInterval((async()=>{N.log("Ping stream translation",i.pingId),this.votClient.pingStream({pingId:i.pingId})}),1e3*i.interval),i}catch(t){return console.error("[VOT] Failed to translate stream",t),await this.updateTranslationErrorMsg(t.data?.message??t),null}}async autoTranslate(){if(this.firstPlay&&1===this.data.autoTranslate&&this.videoData.videoId){this.firstPlay=!1;try{await this.translateExecutor(this.videoData.videoId)}catch(t){console.error("[VOT]",t),this.transformBtn("error","VOTLocalizedError"===t?.name?t.localizedMessage:t)}}}getPreferAudio(){return!this.audioContext||(!this.data.newAudioPlayer||(!!this.videoData.isStream||!(this.data.newAudioPlayer&&!this.data.onlyBypassMediaCSP)&&!this.site.needBypassCSP))}createPlayer(){const t=this.getPreferAudio();return N.log("preferAudio:",t),this.audioPlayer=new bo({video:this.video,debug:!1,fetchFn:it,preferAudio:t}),this}async init(){if(this.initialized)return;const t={autoTranslate:j.get("autoTranslate",0),dontTranslateLanguage:j.get("dontTranslateLanguage",Z),dontTranslateYourLang:j.get("dontTranslateYourLang",1),autoSetVolumeYandexStyle:j.get("autoSetVolumeYandexStyle",1),autoVolume:j.get("autoVolume",F),buttonPos:j.get("buttonPos","default"),showVideoSlider:j.get("showVideoSlider",1),syncVolume:j.get("syncVolume",0),downloadWithName:j.get("downloadWithName",1),subtitlesMaxLength:j.get("subtitlesMaxLength",300),highlightWords:j.get("highlightWords",0),subtitlesFontSize:j.get("subtitlesFontSize",20),subtitlesOpacity:j.get("subtitlesOpacity",20),subtitlesDownloadFormat:j.get("subtitlesDownloadFormat","srt"),responseLanguage:j.get("responseLanguage",Z),defaultVolume:j.get("defaultVolume",100),audioProxy:j.get("audioProxy",0),onlyBypassMediaCSP:j.get("onlyBypassMediaCSP",Number(!!this.audioContext)),newAudioPlayer:j.get("newAudioPlayer",Number(!!this.audioContext)),showPiPButton:j.get("showPiPButton",0),translateAPIErrors:j.get("translateAPIErrors",1),translationService:j.get("translationService",q),detectService:j.get("detectService",U),hotkeyButton:j.get("hotkeyButton",null),m3u8ProxyHost:j.get("m3u8ProxyHost",R),translateProxyEnabled:j.get("translateProxyEnabled",0),proxyWorkerHost:j.get("proxyWorkerHost",$),audioBooster:j.get("audioBooster",0),localeHash:j.get("locale-hash",""),localeUpdatedAt:j.get("locale-updated-at",0)};this.data=Object.fromEntries(await Promise.all(Object.entries(t).map((async([t,e])=>[t,await e])))),console.log("[VOT] data from db: ",this.data),"m3u8-proxy.toil.cc"===this.data.m3u8ProxyHost&&(this.data.m3u8ProxyHost=R,await j.set("m3u8ProxyHost",R),console.log(`[VOT] Old m3u8 proxy host converted to new ${this.data.m3u8ProxyHost} media-proxy`)),"vot.toil.cc"===this.data.proxyWorkerHost&&(this.data.proxyWorkerHost=$,await j.set("proxyWorkerHost",$),console.log(`[VOT] Old proxy worker host converted to new ${this.data.proxyWorkerHost}`)),!this.data.translateProxyEnabled&&GM_info?.scriptHandler&&W.includes(GM_info.scriptHandler)&&(this.data.translateProxyEnabled=1,await j.set("translateProxyEnabled",1),N.log("translateProxyEnabled",this.data.translateProxyEnabled)),N.log("Extension compatibility passed..."),this.votOpts={headers:this.data.translateProxyEnabled?{}:{"sec-ch-ua":null,"sec-ch-ua-mobile":null,"sec-ch-ua-platform":null},fetchFn:it,hostVOT:D,host:this.data.translateProxyEnabled?this.data.proxyWorkerHost:"api.browser.yandex.ru"},this.votClient=new(this.data.translateProxyEnabled?yt:bt)(this.votOpts),this.subtitlesWidget=new Be(this.video,this.container,this.site),this.subtitlesWidget.setMaxLength(this.data.subtitlesMaxLength),this.subtitlesWidget.setHighlightWords(this.data.highlightWords),this.subtitlesWidget.setFontSize(this.data.subtitlesFontSize),this.subtitlesWidget.setOpacity(this.data.subtitlesOpacity),this.initUI(),this.initUIEvents(),this.videoData=await this.getVideoData(),this.createPlayer(),this.setSelectMenuValues(this.videoData.detectedLanguage,this.data.responseLanguage??"ru"),this.translateToLang=this.data.responseLanguage??"ru",this.initExtraEvents(),await Promise.all([this.updateSubtitles(),this.autoTranslate()]),this.initialized=!0}transformBtn(t,e){this.votButton.container.dataset.status=t;const o="error"===t&&e.includes(J.get("translationTake"));return this.setLoadingBtn(o),this.votButton.label.textContent=e,this.votButton.container.title="error"===t?e:"",this}setLoadingBtn(t=!1){return this.votButton.container.dataset.loading=t,this}initUI(){this.votButton=ze.createVOTButton(J.get("translateVideo")),this.votButton.container.style.opacity=0,this.data?.buttonPos&&"default"!==this.data?.buttonPos&&this.container.clientWidth>550?(this.votButton.container.dataset.direction="column",this.votButton.container.dataset.position=this.data?.buttonPos):(this.votButton.container.dataset.direction="row",this.votButton.container.dataset.position="default"),this.container.appendChild(this.votButton.container),this.votButton.pipButton.hidden=!X()||!this.data?.showPiPButton,this.votButton.separator2.hidden=!X()||!this.data?.showPiPButton,this.votButton.container.addEventListener("click",(t=>{t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation()})),this.votMenu=ze.createVOTMenu(J.get("VOTSettings")),this.votMenu.container.dataset.position=this.container.clientWidth&&this.container.clientWidth>550?this.data?.buttonPos:"default",this.container.appendChild(this.votMenu.container),this.votDownloadButton=ze.createIconButton(Gt``,c);const h=He(n,r,s,{onSelectCb:l});return d.append(u.container,c,h.container),{container:d,fromSelect:u,icon:c,toSelect:h}},updateSlider:Fe,animateLoader:function(t,e="139, 180, 245"){const o=t.querySelector(".vot-loader-helper"),i=t.querySelector(".vot-loader-main");anime.timeline({...$e,targets:[o,i],duration:250}).add({"fill-opacity":0,"stroke-width":2,d:"M 12 1.5 C 17.799 1.5 22.5 6.201 22.5 12 C 22.5 17.799 17.799 22.5 12 22.5 C 6.201 22.5 1.5 17.799 1.5 12 C 1.5 6.201 6.201 1.5 12 1.5 Z",duration:0}).add({targets:o,stroke:`rgb(${e})`,"stroke-opacity":0,duration:0},0).add({targets:i,stroke:"#888888","stroke-opacity":.25},0);const a=anime.timeline({targets:o,easing:"easeInOutSine",duration:1e3,autoplay:!1}).add({strokeOpacity:1,duration:0},0).add({strokeDashoffset:[anime.setDashoffset,0]},0);return t=>{a.seek(a.duration*(t/100))}},afterAnimateLoader:function(t,e="139, 180, 245"){const o=t.querySelector(".vot-loader-helper"),i=t.querySelector(".vot-loader-main");anime.timeline({...$e,targets:i,duration:600}).add({d:"M 9.0596 14.8571 L 9.7667 15.5642 L 10.4738 14.8571 L 17.0071 8.3238 C 17.0457 8.2852 17.0937 8.25 17.2333 8.25 C 17.373 8.25 17.421 8.2852 17.4596 8.3238 C 17.4981 8.3624 17.5333 8.4104 17.5333 8.55 C 17.5333 8.6896 17.4981 8.7376 17.4596 8.7762 L 9.9929 16.2429 C 9.9011 16.3346 9.8397 16.35 9.7667 16.35 C 9.6937 16.35 9.6322 16.3346 9.5404 16.2429 L 6.0738 12.7762 C 6.0352 12.7376 6 12.6897 6 12.55 C 6 12.4103 6.0352 12.3624 6.0738 12.3238 C 6.1124 12.2852 6.1603 12.25 6.3 12.25 C 6.4397 12.25 6.4876 12.2852 6.5262 12.3238 L 9.0596 14.8571 Z",duration:0}).add({strokeDashoffset:[anime.setDashoffset,0],stroke:`rgb(${e})`,"stroke-opacity":1}),setTimeout((()=>{anime.timeline({...$e,targets:i,duration:600}).add({d:"M12 15.575C11.8667 15.575 11.7417 15.5542 11.625 15.5125C11.5083 15.4708 11.4 15.4 11.3 15.3L7.7 11.7C7.5 11.5 7.40417 11.2667 7.4125 11C7.42083 10.7333 7.51667 10.5 7.7 10.3C7.9 10.1 8.1375 9.99583 8.4125 9.9875C8.6875 9.97917 8.925 10.075 9.125 10.275L11 12.15V5C11 4.71667 11.0958 4.47917 11.2875 4.2875C11.4792 4.09583 11.7167 4 12 4C12.2833 4 12.5208 4.09583 12.7125 4.2875C12.9042 4.47917 13 4.71667 13 5V12.15L14.875 10.275C15.075 10.075 15.3125 9.97917 15.5875 9.9875C15.8625 9.99583 16.1 10.1 16.3 10.3C16.4833 10.5 16.5792 10.7333 16.5875 11C16.5958 11.2667 16.5 11.5 16.3 11.7L12.7 15.3C12.6 15.4 12.4917 15.4708 12.375 15.5125C12.2583 15.5542 12.1333 15.575 12 15.575ZM6 20C5.45 20 4.97917 19.8042 4.5875 19.4125C4.19583 19.0208 4 18.55 4 18V16C4 15.7167 4.09583 15.4792 4.2875 15.2875C4.47917 15.0958 4.71667 15 5 15C5.28333 15 5.52083 15.0958 5.7125 15.2875C5.90417 15.4792 6 15.7167 6 16V18H18V16C18 15.7167 18.0958 15.4792 18.2875 15.2875C18.4792 15.0958 18.7167 15 19 15C19.2833 15 19.5208 15.0958 19.7125 15.2875C19.9042 15.4792 20 15.7167 20 16V18C20 18.55 19.8042 19.0208 19.4125 19.4125C19.0208 19.8042 18.55 20 18 20H6Z",duration:100}).add({targets:o,d:"",duration:200},0).add({targets:i,"stroke-width":"0",stroke:`rgba(${e}), 0)`,"fill-opacity":"1","stroke-dasharray":"0","stroke-dashoffset":"0",duration:0})}),2e3)},createDetails:function(t){const e=document.createElement("vot-block");e.classList.add("vot-details");const o=document.createElement("vot-block");o.append(t);const i=document.createElement("vot-block");return i.classList.add("vot-details-arrow-icon"),ue(Re,i),e.append(o,i),{container:e,header:o,arrowIcon:i}}};o("./node_modules/requestidlecallback-polyfill/index.js");class We{constructor(){this.listeners=new Set}hasListener(t){return this.listeners.has(t)}dispatchToListener(t,...e){try{t(...e)}catch(t){console.error("[VOT]",t)}}addListener(t){if(this.hasListener(t))throw new Error("[VOT] The listener has already been added.");this.listeners.add(t)}removeListener(t){if(!this.hasListener(t))throw new Error("[VOT] The listener has not been added yet.");this.listeners.delete(t)}dispatch(...t){for(const e of Array.from(this.listeners))this.dispatchToListener(e,...t)}}const je=new Set(["advertise","promo","sponsor","banner","commercial","preroll","midroll","postroll","ad-container","sponsored"]),Ge=(()=>{const t=Array.from(je).join("|");return new RegExp(t,"i")})(),Ye=t=>{const e=[];for(let o=0;o=0||(o=(t.length-i)/2);const a=2*o;this.ensureCapacity(o+this._frameCount);const n=this.endIndex;this.vector.set(t.subarray(i,i+a),n),this._frameCount+=o}putBuffer(t,e,o=0){e=e||0,o>=0||(o=t.frameCount-e),this.putSamples(t.vector,t.position+e,o)}receive(t){t>=0&&!(t>this._frameCount)||(t=this.frameCount),this._frameCount-=t,this._position+=t}receiveSamples(t,e=0){const o=2*e,i=this.startIndex;t.set(this._vector.subarray(i,i+o)),this.receive(e)}extract(t,e=0,o=0){const i=this.startIndex+2*e,a=2*o;t.set(this._vector.subarray(i,i+a))}ensureCapacity(t=0){const e=parseInt(2*t);if(this._vector.length0&&(this._vector.set(this._vector.subarray(this.startIndex,this.endIndex)),this._position=0)}}class Ze{constructor(t){t?(this._inputBuffer=new Ke,this._outputBuffer=new Ke):this._inputBuffer=this._outputBuffer=null}get inputBuffer(){return this._inputBuffer}set inputBuffer(t){this._inputBuffer=t}get outputBuffer(){return this._outputBuffer}set outputBuffer(t){this._outputBuffer=t}clear(){this._inputBuffer.clear(),this._outputBuffer.clear()}}class Xe extends Ze{constructor(t){super(t),this.reset(),this._rate=1}set rate(t){this._rate=t}reset(){this.slopeCount=0,this.prevSampleL=0,this.prevSampleR=0}clone(){const t=new Xe;return t.rate=this._rate,t}process(){const t=this._inputBuffer.frameCount;this._outputBuffer.ensureAdditionalCapacity(t/this._rate+1);const e=this.transpose(t);this._inputBuffer.receive(),this._outputBuffer.put(e)}transpose(t=0){if(0===t)return 0;const e=this._inputBuffer.vector,o=this._inputBuffer.startIndex,i=this._outputBuffer.vector,a=this._outputBuffer.endIndex;let n=0,r=0;for(;this.slopeCount<1;)i[a+2*r]=(1-this.slopeCount)*this.prevSampleL+this.slopeCount*e[o],i[a+2*r+1]=(1-this.slopeCount)*this.prevSampleR+this.slopeCount*e[o+1],r+=1,this.slopeCount+=this._rate;if(this.slopeCount-=1,1!==t)t:for(;;){for(;this.slopeCount>1;)if(this.slopeCount-=1,n+=1,n>=t-1)break t;const s=o+2*n;i[a+2*r]=(1-this.slopeCount)*e[s]+this.slopeCount*e[s+2],i[a+2*r+1]=(1-this.slopeCount)*e[s+1]+this.slopeCount*e[s+3],r+=1,this.slopeCount+=this._rate}return this.prevSampleL=e[o+2*t-2],this.prevSampleR=e[o+2*t-1],r}}class Qe{constructor(t){this._pipe=t}get pipe(){return this._pipe}get inputBuffer(){return this._pipe.inputBuffer}get outputBuffer(){return this._pipe.outputBuffer}fillInputBuffer(){throw new Error("fillInputBuffer() not overridden")}fillOutputBuffer(t=0){for(;this.outputBuffer.frameCountthis._position)throw new RangeError("New position may not be greater than current position");const e=this.outputBufferPosition-(this._position-t);if(e<0)throw new RangeError("New position falls outside of history buffer");this.outputBufferPosition=e,this._position=t}get sourcePosition(){return this._sourcePosition}set sourcePosition(t){this.clear(),this._sourcePosition=t}onEnd(){this.callback()}fillInputBuffer(t=0){const e=new Float32Array(2*t),o=this.sourceSound.extract(e,t,this._sourcePosition);this._sourcePosition+=o,this.inputBuffer.putSamples(e,0,o)}extract(t,e=0){this.fillOutputBuffer(this.outputBufferPosition+e);const o=Math.min(e,this.outputBuffer.frameCount-this.outputBufferPosition);this.outputBuffer.extract(t,this.outputBufferPosition,o);const i=this.outputBufferPosition+o;return this.outputBufferPosition=Math.min(this.historyBufferSize,i),this.outputBuffer.receive(Math.max(i-this.historyBufferSize,0)),this._position+=o,o}handleSampleData(t){this.extract(t.data,4096)}clear(){super.clear(),this.outputBufferPosition=0}}const oo=[[124,186,248,310,372,434,496,558,620,682,744,806,868,930,992,1054,1116,1178,1240,1302,1364,1426,1488,0],[-100,-75,-50,-25,25,50,75,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[-20,-15,-10,-5,5,10,15,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[-4,-3,-2,-1,1,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],io=-10/1.5;class ao extends Ze{constructor(t){super(t),this._quickSeek=!0,this.midBufferDirty=!1,this.midBuffer=null,this.overlapLength=0,this.autoSeqSetting=!0,this.autoSeekSetting=!0,this._tempo=1,this.setParameters(44100,0,0,8)}clear(){super.clear(),this.clearMidBuffer()}clearMidBuffer(){this.midBufferDirty&&(this.midBufferDirty=!1,this.midBuffer=null)}setParameters(t,e,o,i){t>0&&(this.sampleRate=t),i>0&&(this.overlapMs=i),e>0?(this.sequenceMs=e,this.autoSeqSetting=!1):this.autoSeqSetting=!0,o>0?(this.seekWindowMs=o,this.autoSeekSetting=!1):this.autoSeekSetting=!0,this.calculateSequenceParameters(),this.calculateOverlapLength(this.overlapMs),this.tempo=this._tempo}set tempo(t){let e;this._tempo=t,this.calculateSequenceParameters(),this.nominalSkip=this._tempo*(this.seekWindowLength-this.overlapLength),this.skipFract=0,e=Math.floor(this.nominalSkip+.5),this.sampleReq=Math.max(e+this.overlapLength,this.seekWindowLength)+this.seekLength}get tempo(){return this._tempo}get inputChunkSize(){return this.sampleReq}get outputChunkSize(){return this.overlapLength+Math.max(0,this.seekWindowLength-2*this.overlapLength)}calculateOverlapLength(t=0){let e;e=this.sampleRate*t/1e3,e=e<16?16:e,e-=e%8,this.overlapLength=e,this.refMidBuffer=new Float32Array(2*this.overlapLength),this.midBuffer=new Float32Array(2*this.overlapLength)}checkLimits(t,e,o){return to?o:t}calculateSequenceParameters(){let t,e;this.autoSeqSetting&&(t=150+-50*this._tempo,t=this.checkLimits(t,50,125),this.sequenceMs=Math.floor(t+.5)),this.autoSeekSetting&&(e=28.333333333333332+io*this._tempo,e=this.checkLimits(e,15,25),this.seekWindowMs=Math.floor(e+.5)),this.seekWindowLength=Math.floor(this.sampleRate*this.sequenceMs/1e3),this.seekLength=Math.floor(this.sampleRate*this.seekWindowMs/1e3)}set quickSeek(t){this._quickSeek=t}clone(){const t=new ao;return t.tempo=this._tempo,t.setParameters(this.sampleRate,this.sequenceMs,this.seekWindowMs,this.overlapMs),t}seekBestOverlapPosition(){return this._quickSeek?this.seekBestOverlapPositionStereoQuick():this.seekBestOverlapPositionStereo()}seekBestOverlapPositionStereo(){let t,e,o,i=0;for(this.preCalculateCorrelationReferenceStereo(),t=0,e=Number.MIN_VALUE;ie&&(e=o,t=i);return t}seekBestOverlapPositionStereoQuick(){let t,e,o,i,a,n=0;for(this.preCalculateCorrelationReferenceStereo(),e=Number.MIN_VALUE,t=0,i=0,a=0;n<4;n+=1){let r=0;for(;oo[n][r]&&(a=i+oo[n][r],!(a>=this.seekLength));)o=this.calculateCrossCorrelationStereo(2*a,this.refMidBuffer),o>e&&(e=o,t=a),r+=1;i=t}return t}preCalculateCorrelationReferenceStereo(){let t,e,o=0;for(;o=this.sampleReq;){t=this.seekBestOverlapPosition(),this._outputBuffer.ensureAdditionalCapacity(this.overlapLength),this.overlap(Math.floor(t)),this._outputBuffer.put(this.overlapLength),e=this.seekWindowLength-2*this.overlapLength,e>0&&this._outputBuffer.putBuffer(this._inputBuffer,t+this.overlapLength,e);const i=this._inputBuffer.startIndex+2*(t+this.seekWindowLength-this.overlapLength);this.midBuffer.set(this._inputBuffer.vector.subarray(i,i+2*this.overlapLength)),this.skipFract+=this.nominalSkip,o=Math.floor(this.skipFract),this.skipFract-=o,this._inputBuffer.receive(o)}}}const no=function(t,e){return(t>e?t-e:e-t)>1e-10};class ro{constructor(){this.transposer=new Xe(!1),this.stretch=new ao(!1),this._inputBuffer=new Ke,this._intermediateBuffer=new Ke,this._outputBuffer=new Ke,this._rate=0,this._tempo=0,this.virtualPitch=1,this.virtualRate=1,this.virtualTempo=1,this.calculateEffectiveRateAndTempo()}clear(){this.transposer.clear(),this.stretch.clear()}clone(){const t=new ro;return t.rate=this.rate,t.tempo=this.tempo,t}get rate(){return this._rate}set rate(t){this.virtualRate=t,this.calculateEffectiveRateAndTempo()}set rateChange(t){this._rate=1+.01*t}get tempo(){return this._tempo}set tempo(t){this.virtualTempo=t,this.calculateEffectiveRateAndTempo()}set tempoChange(t){this.tempo=1+.01*t}set pitch(t){this.virtualPitch=t,this.calculateEffectiveRateAndTempo()}set pitchOctaves(t){this.pitch=Math.exp(.69314718056*t),this.calculateEffectiveRateAndTempo()}set pitchSemitones(t){this.pitchOctaves=t/12}get inputBuffer(){return this._inputBuffer}get outputBuffer(){return this._outputBuffer}calculateEffectiveRateAndTempo(){const t=this._tempo,e=this._rate;this._tempo=this.virtualTempo/this.virtualPitch,this._rate=this.virtualRate*this.virtualPitch,no(this._tempo,t)&&(this.stretch.tempo=this._tempo),no(this._rate,e)&&(this.transposer.rate=this._rate),this._rate>1?this._outputBuffer!=this.transposer.outputBuffer&&(this.stretch.inputBuffer=this._inputBuffer,this.stretch.outputBuffer=this._intermediateBuffer,this.transposer.inputBuffer=this._intermediateBuffer,this.transposer.outputBuffer=this._outputBuffer):this._outputBuffer!=this.stretch.outputBuffer&&(this.transposer.inputBuffer=this._inputBuffer,this.transposer.outputBuffer=this._intermediateBuffer,this.stretch.inputBuffer=this._intermediateBuffer,this.stretch.outputBuffer=this._outputBuffer)}process(){this._rate>1?(this.stretch.process(),this.transposer.process()):(this.transposer.process(),this.stretch.process())}}class so{constructor(t){this.buffer=t,this._position=0}get dualChannel(){return this.buffer.numberOfChannels>1}get position(){return this._position}set position(t){this._position=t}extract(t,e=0,o=0){this.position=o;let i=this.buffer.getChannelData(0),a=this.dualChannel?this.buffer.getChannelData(1):this.buffer.getChannelData(0),n=0;for(;n=e?t:new Array(e-t.length+1).join(o)+t}(parseInt(t-60*e),2)}`},uo=function(t){const e=this.timePlayed,o=this.sampleRate;if(this.sourcePosition=t,this.timePlayed=t/o,e!==this.timePlayed){const t=new CustomEvent("play",{detail:{timePlayed:this.timePlayed,formattedTimePlayed:this.formattedTimePlayed,percentagePlayed:this.percentagePlayed}});this._node.dispatchEvent(t)}};class co{constructor(t,e,o,i=to){this._soundtouch=new ro;const a=new so(e);this.timePlayed=0,this.sourcePosition=0,this._filter=new eo(a,this._soundtouch,i),this._node=function(t,e,o=to,i=4096){const a=t.createScriptProcessor(i,2,2),n=new Float32Array(2*i);return a.onaudioprocess=t=>{let a=t.outputBuffer.getChannelData(0),r=t.outputBuffer.getChannelData(1),s=e.extract(n,i);o(e.sourcePosition),0===s&&e.onEnd();let l=0;for(;luo.call(this,t)),o),this.tempo=1,this.rate=1,this.duration=e.duration,this.sampleRate=t.sampleRate,this.listeners=[]}get formattedDuration(){return lo(this.duration)}get formattedTimePlayed(){return lo(this.timePlayed)}get percentagePlayed(){return 100*this._filter.sourcePosition/(this.duration*this.sampleRate)}set percentagePlayed(t){this._filter.sourcePosition=parseInt(t*this.duration*this.sampleRate),this.sourcePosition=this._filter.sourcePosition,this.timePlayed=this.sourcePosition/this.sampleRate}get node(){return this._node}set pitch(t){this._soundtouch.pitch=t}set pitchSemitones(t){this._soundtouch.pitchSemitones=t}set rate(t){this._soundtouch.rate=t}set tempo(t){this._soundtouch.tempo=t}connect(t){this._node.connect(t)}disconnect(){this._node.disconnect()}on(t,e){this.listeners.push({name:t,cb:e}),this._node.addEventListener(t,(t=>e(t.detail)))}off(t=null){let e=this.listeners;t&&(e=e.filter((e=>e.name===t))),e.forEach((t=>{this._node.removeEventListener(t.name,(e=>t.cb(e.detail)))}))}}const ho=(...t)=>{if(Je.debug)return console.log(`%c✦ chaimu.js v${Je.version} ✦`,"background: #000; color: #fff; padding: 0 8px",...t)},po=["playing","ratechange","play","waiting","pause","seeked"];function go(){const t=window.AudioContext||window.webkitAudioContext;return t?new t:void 0}class mo{static name="BasePlayer";chaimu;_src;fetch;constructor(t,e){this.chaimu=t,this._src=e,this.fetch=Je.fetchFn}async init(){return new Promise((t=>t(this)))}clear(){return new Promise((t=>t(this)))}lipSync(t=!1){return this}handleVideoEvent=t=>(ho(`handle video ${t.type}`),this.lipSync(t.type),this);removeVideoEvents(){for(const t of po)this.chaimu.video.removeEventListener(t,this.handleVideoEvent);return this}addVideoEvents(){for(const t of po)this.chaimu.video.addEventListener(t,this.handleVideoEvent);return this}async play(){return new Promise((t=>t(this)))}async pause(){return new Promise((t=>t(this)))}get name(){return this.constructor.name}set src(t){this._src=t}get src(){return this._src}get currentSrc(){return this._src}set volume(t){}get volume(){return 0}get playbackRate(){return 0}set playbackRate(t){}get currentTime(){return 0}}class vo extends mo{static name="AudioPlayer";audio;gainNode;audioSource;constructor(t,e){super(t,e),this.audio=new Audio(e),this.audio.crossOrigin="anonymous"}initAudioBooster(){return this.chaimu.audioContext?(this.gainNode&&this.audioSource&&(this.audioSource.disconnect(this.gainNode),this.gainNode.disconnect()),this.gainNode=this.chaimu.audioContext.createGain(),this.gainNode.connect(this.chaimu.audioContext.destination),this.audioSource=this.chaimu.audioContext.createMediaElementSource(this.audio),this.audioSource.connect(this.gainNode),this):this}async init(){return new Promise((t=>(this.initAudioBooster(),t(this))))}audioErrorHandle=t=>{console.error("[AudioPlayer]",t)};lipSync(t=!1){if(ho("[AudioPlayer] lipsync video",this.chaimu.video),!this.chaimu.video)return this;if(this.audio.currentTime=this.chaimu.video.currentTime,this.audio.playbackRate=this.chaimu.video.playbackRate,!t)return ho("[AudioPlayer] lipsync mode isn't set"),this;switch(ho(`[AudioPlayer] lipsync mode is ${t}`),t){case"play":case"playing":case"seeked":return this.chaimu.video.paused||this.syncPlay(),this;case"pause":case"waiting":return this.pause(),this;default:return this}}async clear(){return new Promise((t=>(this.audio.pause(),this.audio.src="",this.audio.removeAttribute("src"),t(this))))}syncPlay(){return ho("[AudioPlayer] sync play called"),this.audio.play().catch(this.audioErrorHandle),this}async play(){return ho("[AudioPlayer] play called"),await this.audio.play().catch(this.audioErrorHandle),this}async pause(){return new Promise((t=>(ho("[AudioPlayer] pause called"),this.audio.pause(),t(this))))}set src(t){this._src=t,t?this.audio.src=t:this.clear()}get src(){return this._src}get currentSrc(){return this.audio.currentSrc}set volume(t){this.gainNode?this.gainNode.gain.value=t:this.audio.volume=t}get volume(){return this.gainNode?this.gainNode.gain.value:this.audio.volume}get playbackRate(){return this.audio.playbackRate}set playbackRate(t){this.audio.playbackRate=t}get currentTime(){return this.audio.currentTime}}class fo extends mo{static name="ChaimuPlayer";audioBuffer;sourceNode;gainNode;audioShifter;cleanerRunned=!1;async fetchAudio(){if(!this._src)throw new Error("No audio source provided");if(!this.chaimu.audioContext)throw new Error("No audio context available");ho(`[ChaimuPlayer] Fetching audio from ${this._src}...`);try{const t=await this.fetch(this._src);ho("[ChaimuPlayer] Decoding fetched audio...");const e=await t.arrayBuffer();this.audioBuffer=await this.chaimu.audioContext.decodeAudioData(e)}catch(t){throw new Error(`Failed to fetch audio file, because ${t.message}`)}return this}initAudioBooster(){return this.chaimu.audioContext?(this.gainNode&&this.gainNode.disconnect(),this.gainNode=this.chaimu.audioContext.createGain(),this):this}async init(){return await this.fetchAudio(),this.initAudioBooster(),this}lipSync(t=!1){if(ho("[ChaimuPlayer] lipsync video",this.chaimu.video,this),!this.chaimu.video)return this;if(!t)return ho("[ChaimuPlayer] lipsync mode isn't set"),this;switch(ho(`[ChaimuPlayer] lipsync mode is ${t}`),t){case"play":case"playing":case"ratechange":case"seeked":return this.chaimu.video.paused||this.start(),this;case"pause":case"waiting":return this.pause(),this;default:return this}}async reopenCtx(){if(!this.chaimu.audioContext)throw new Error("No audio context available");try{await this.chaimu.audioContext.close()}catch{}return this}async clear(){if(!this.chaimu.audioContext)throw new Error("No audio context available");if(ho("clear audio context"),this.cleanerRunned=!0,await this.pause(),!this.gainNode)return this.cleanerRunned=!1,this;this.sourceNode&&(this.sourceNode.stop(),this.sourceNode.disconnect(this.gainNode),this.sourceNode=void 0),this.audioShifter&&(this.audioShifter._node.disconnect(this.gainNode),this.audioShifter=void 0),this.gainNode.disconnect();const t=this.volume;return this.gainNode=void 0,await this.reopenCtx(),this.chaimu.audioContext=go(),this.initAudioBooster(),this.volume=t,this.cleanerRunned=!1,this}async start(){if(!this.chaimu.audioContext)throw new Error("No audio context available");if(!this.audioBuffer)throw new Error("The player isn't initialized");return!this.gainNode||this.audioShifter&&this.audioShifter.duration({label:J.get("langs")[t]??t.toUpperCase(),value:t,selected:e===t})))}const xo=t=>t?J.get("VOTChangeHotkeyWithCurrent").replace("{0}",t.replace("Key","")):J.get("VOTCreateTranslationHotkey");class So{translateFromLang="en";translateToLang=Z;timer;videoData="";firstPlay=!0;audioContext=go();hls=Q();votClient;audioPlayer;videoTranslations=[];videoTranslationTTL=7200;cachedTranslation;downloadTranslationUrl=null;autoRetry;streamPing;votOpts;volumeOnStart;tempOriginalVolume;tempVolume;firstSyncVolume=!0;subtitlesList=[];subtitlesListVideoId=null;dragging;constructor(t,e,o){N.log("[VideoHandler] add video:",t,"container:",e,this),this.video=t,this.container=e,this.site=o,this.init()}async translateVideoImpl(t,e,o,i=null){if(clearTimeout(this.autoRetry),N.log(t,`Translate video (requestLang: ${e}, responseLang: ${o})`),await pt(this.site,this.video)!==t.videoId)return null;try{const a=await this.votClient.translateVideo({videoData:t,requestLang:e,responseLang:o,translationHelp:i});if(N.log("Translate video result",a),a.translated&&a.remainingTime<1)return N.log("Video translation finished with this data: ",a),a;await this.updateTranslationErrorMsg(a.remainingTime>0?function(t){const e=Math.floor(t/60),o=Math.floor(t%60);return e>=60?J.get("translationTakeMoreThanHour"):1===e||0===e&&o>0?J.get("translationTakeAboutMinute"):11!==e&&e%10==1?J.get("translationTakeApproximatelyMinute2").replace("{0}",e):![12,13,14].includes(e)&&[2,3,4].includes(e%10)?J.get("translationTakeApproximatelyMinute").replace("{0}",e):J.get("translationTakeApproximatelyMinutes").replace("{0}",e)}(a.remainingTime):a.message??J.get("translationTakeFewMinutes"))}catch(t){return console.error("[VOT] Failed to translate video",t),await this.updateTranslationErrorMsg(t.data?.message??t),null}return new Promise((a=>{const n=this.subtitlesList.some((t=>"yandex"===t.source))?2e4:3e4;this.autoRetry=setTimeout((async()=>{const n=await this.translateVideoImpl(t,e,o,i);(!n||n.translated&&n.remainingTime<1)&&a(n)}),n)}))}async translateStreamImpl(t,e,o){if(clearTimeout(this.autoRetry),N.log(t,`Translate stream (requestLang: ${e}, responseLang: ${o})`),await pt(this.site,this.video)!==t.videoId)return null;try{const i=await this.votClient.translateStream({videoData:t,requestLang:e,responseLang:o});if(N.log("Translate stream result",i),!i.translated&&10===i.interval)return await this.updateTranslationErrorMsg(J.get("translationTakeFewMinutes")),new Promise((a=>{this.autoRetry=setTimeout((async()=>{const i=await this.translateStreamImpl(t,e,o);i&&!i.translated&&10===i.interval||a(i)}),1e3*i.interval)}));if(i.message)throw N.log(`Stream translation aborted! Message: ${i.message}`),new mt("streamNoConnectionToServer");if(!i.result)throw N.log("Failed to find translation result! Data:",i),new mt("audioNotReceived");return N.log("Stream translated successfully. Running...",i),this.streamPing=setInterval((async()=>{N.log("Ping stream translation",i.pingId),this.votClient.pingStream({pingId:i.pingId})}),1e3*i.interval),i}catch(t){return console.error("[VOT] Failed to translate stream",t),await this.updateTranslationErrorMsg(t.data?.message??t),null}}async autoTranslate(){if(this.firstPlay&&1===this.data.autoTranslate&&this.videoData.videoId){this.firstPlay=!1;try{await this.translateExecutor(this.videoData.videoId)}catch(t){console.error("[VOT]",t),this.transformBtn("error","VOTLocalizedError"===t?.name?t.localizedMessage:t)}}}getPreferAudio(){return!this.audioContext||(!this.data.newAudioPlayer||(!!this.videoData.isStream||!(this.data.newAudioPlayer&&!this.data.onlyBypassMediaCSP)&&!this.site.needBypassCSP))}createPlayer(){const t=this.getPreferAudio();return N.log("preferAudio:",t),this.audioPlayer=new bo({video:this.video,debug:!1,fetchFn:it,preferAudio:t}),this}async init(){if(this.initialized)return;const t={autoTranslate:j.get("autoTranslate",0),dontTranslateLanguage:j.get("dontTranslateLanguage",Z),dontTranslateYourLang:j.get("dontTranslateYourLang",1),autoSetVolumeYandexStyle:j.get("autoSetVolumeYandexStyle",1),autoVolume:j.get("autoVolume",F),buttonPos:j.get("buttonPos","default"),showVideoSlider:j.get("showVideoSlider",1),syncVolume:j.get("syncVolume",0),downloadWithName:j.get("downloadWithName",1),subtitlesMaxLength:j.get("subtitlesMaxLength",300),highlightWords:j.get("highlightWords",0),subtitlesFontSize:j.get("subtitlesFontSize",20),subtitlesOpacity:j.get("subtitlesOpacity",20),subtitlesDownloadFormat:j.get("subtitlesDownloadFormat","srt"),responseLanguage:j.get("responseLanguage",Z),defaultVolume:j.get("defaultVolume",100),audioProxy:j.get("audioProxy",0),onlyBypassMediaCSP:j.get("onlyBypassMediaCSP",Number(!!this.audioContext)),newAudioPlayer:j.get("newAudioPlayer",Number(!!this.audioContext)),showPiPButton:j.get("showPiPButton",0),translateAPIErrors:j.get("translateAPIErrors",1),translationService:j.get("translationService",q),detectService:j.get("detectService",U),hotkeyButton:j.get("hotkeyButton",null),m3u8ProxyHost:j.get("m3u8ProxyHost",R),translateProxyEnabled:j.get("translateProxyEnabled",0),proxyWorkerHost:j.get("proxyWorkerHost",$),audioBooster:j.get("audioBooster",0),localeHash:j.get("locale-hash",""),localeUpdatedAt:j.get("locale-updated-at",0)};this.data=Object.fromEntries(await Promise.all(Object.entries(t).map((async([t,e])=>[t,await e])))),console.log("[VOT] data from db: ",this.data),"m3u8-proxy.toil.cc"===this.data.m3u8ProxyHost&&(this.data.m3u8ProxyHost=R,await j.set("m3u8ProxyHost",R),console.log(`[VOT] Old m3u8 proxy host converted to new ${this.data.m3u8ProxyHost} media-proxy`)),"vot.toil.cc"===this.data.proxyWorkerHost&&(this.data.proxyWorkerHost=$,await j.set("proxyWorkerHost",$),console.log(`[VOT] Old proxy worker host converted to new ${this.data.proxyWorkerHost}`)),!this.data.translateProxyEnabled&&GM_info?.scriptHandler&&W.includes(GM_info.scriptHandler)&&(this.data.translateProxyEnabled=1,await j.set("translateProxyEnabled",1),N.log("translateProxyEnabled",this.data.translateProxyEnabled)),N.log("Extension compatibility passed..."),this.votOpts={headers:this.data.translateProxyEnabled?{}:{"sec-ch-ua":null,"sec-ch-ua-mobile":null,"sec-ch-ua-platform":null},fetchFn:it,hostVOT:D,host:this.data.translateProxyEnabled?this.data.proxyWorkerHost:"api.browser.yandex.ru"},this.votClient=new(this.data.translateProxyEnabled?yt:bt)(this.votOpts),this.subtitlesWidget=new Be(this.video,this.container,this.site),this.subtitlesWidget.setMaxLength(this.data.subtitlesMaxLength),this.subtitlesWidget.setHighlightWords(this.data.highlightWords),this.subtitlesWidget.setFontSize(this.data.subtitlesFontSize),this.subtitlesWidget.setOpacity(this.data.subtitlesOpacity),this.initUI(),this.initUIEvents(),this.videoData=await this.getVideoData(),this.createPlayer(),this.setSelectMenuValues(this.videoData.detectedLanguage,this.data.responseLanguage??"ru"),this.translateToLang=this.data.responseLanguage??"ru",this.initExtraEvents(),await Promise.all([this.updateSubtitles(),this.autoTranslate()]),this.initialized=!0}transformBtn(t,e){this.votButton.container.dataset.status=t;const o="error"===t&&e.includes(J.get("translationTake"));return this.setLoadingBtn(o),this.votButton.label.textContent=e,this.votButton.container.title="error"===t?e:"",this}setLoadingBtn(t=!1){return this.votButton.container.dataset.loading=t,this}initUI(){this.votButton=ze.createVOTButton(J.get("translateVideo")),this.votButton.container.style.opacity=0,this.data?.buttonPos&&"default"!==this.data?.buttonPos&&this.container.clientWidth>550?(this.votButton.container.dataset.direction="column",this.votButton.container.dataset.position=this.data?.buttonPos):(this.votButton.container.dataset.direction="row",this.votButton.container.dataset.position="default"),this.container.appendChild(this.votButton.container),this.votButton.pipButton.hidden=!X()||!this.data?.showPiPButton,this.votButton.separator2.hidden=!X()||!this.data?.showPiPButton,this.votButton.container.addEventListener("click",(t=>{t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation()})),this.votMenu=ze.createVOTMenu(J.get("VOTSettings")),this.votMenu.container.dataset.position=this.container.clientWidth&&this.container.clientWidth>550?this.data?.buttonPos:"default",this.container.appendChild(this.votMenu.container),this.votDownloadButton=ze.createIconButton(Gt`${this.data?.defaultVolume??100}%`,this.data?.defaultVolume??100,0,this.data.audioBooster?900:100),this.votVideoTranslationVolumeSlider.container.hidden="success"!==this.votButton.container.dataset.status,this.votMenu.bodyContainer.appendChild(this.votVideoTranslationVolumeSlider.container),this.votMenu.container.addEventListener("click",(t=>{t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation()})),this.votSettingsDialog=ze.createDialog(J.get("VOTSettings")),document.documentElement.appendChild(this.votSettingsDialog.container),this.votTranslationHeader=ze.createHeader(J.get("translationSettings")),this.votSettingsDialog.bodyContainer.appendChild(this.votTranslationHeader),this.votAutoTranslateCheckbox=ze.createCheckbox(J.get("VOTAutoTranslate"),this.data?.autoTranslate??!1),this.votSettingsDialog.bodyContainer.appendChild(this.votAutoTranslateCheckbox.container),this.votDontTranslateYourLangSelect=ze.createVOTSelect(J.get("langs")[this.data.dontTranslateLanguage],J.get("VOTDontTranslateYourLang"),wo(st,this.data.dontTranslateLanguage),{onSelectCb:async t=>{this.data.dontTranslateLanguage=t.target.dataset.votValue,await j.set("dontTranslateLanguage",this.data.dontTranslateLanguage)},labelElement:ze.createCheckbox(J.get("VOTDontTranslateYourLang"),this.data?.dontTranslateYourLang??!0).container}),this.votSettingsDialog.bodyContainer.appendChild(this.votDontTranslateYourLangSelect.container),this.changehotkeyButton=ze.createOutlinedButton(xo(this.data.hotkeyButton)),this.votSettingsDialog.bodyContainer.appendChild(this.changehotkeyButton),this.votAutoSetVolumeCheckbox=ze.createCheckbox(`${J.get("VOTAutoSetVolume")}`,this.data?.autoSetVolumeYandexStyle??!0),this.votSettingsDialog.bodyContainer.appendChild(this.votAutoSetVolumeCheckbox.container),this.votAutoSetVolumeSlider=ze.createSlider(jt`${Math.round(100*(this.data?.autoVolume??F))}%`,Math.round(100*(this.data?.autoVolume??F)),0,100),this.votSettingsDialog.bodyContainer.appendChild(this.votAutoSetVolumeSlider.container),this.votShowVideoSliderCheckbox=ze.createCheckbox(J.get("VOTShowVideoSlider"),this.data?.showVideoSlider??!1),this.votSettingsDialog.bodyContainer.appendChild(this.votShowVideoSliderCheckbox.container),this.votAudioBoosterCheckbox=ze.createCheckbox(J.get("VOTAudioBooster"),this.data?.audioBooster??!1),this.audioContext||(this.votAudioBoosterCheckbox.input.disabled=!0,this.votAudioBoosterCheckbox.container.title=J.get("VOTNeedWebAudioAPI")),this.votSettingsDialog.bodyContainer.appendChild(this.votAudioBoosterCheckbox.container),this.votSyncVolumeCheckbox=ze.createCheckbox(J.get("VOTSyncVolume"),this.data?.syncVolume??!1),this.votSettingsDialog.bodyContainer.appendChild(this.votSyncVolumeCheckbox.container),this.votDownloadWithNameCheckbox=ze.createCheckbox(J.get("VOTDownloadWithName"),this.data?.downloadWithName??!1),this.votSettingsDialog.bodyContainer.appendChild(this.votDownloadWithNameCheckbox.container),this.votTranslationServiceSelect=ze.createVOTSelect(this.data.translationService.toUpperCase(),J.get("VOTTranslationService"),wo(ke,this.data.translationService),{onSelectCb:async t=>{this.data.translationService=t.target.dataset.votValue,await j.set("translationService",this.data.translationService)},labelElement:ze.createCheckbox(J.get("VOTTranslateAPIErrors"),this.data.translateAPIErrors??!0).container}),this.votTranslationServiceSelect.container.hidden="ru"===J.lang,this.votSettingsDialog.bodyContainer.appendChild(this.votTranslationServiceSelect.container),this.votDetectServiceSelect=ze.createVOTSelect(this.data.detectService.toUpperCase(),J.get("VOTDetectService"),wo(Te,this.data.detectService),{onSelectCb:async t=>{this.data.detectService=t.target.dataset.votValue,await j.set("detectService",this.data.detectService)},labelElement:ze.createVOTSelectLabel(J.get("VOTDetectService"))}),this.votSettingsDialog.bodyContainer.appendChild(this.votDetectServiceSelect.container),this.votSubtitlesHeader=ze.createHeader(J.get("subtitlesSettings")),this.votSettingsDialog.bodyContainer.appendChild(this.votSubtitlesHeader),this.votSubtitlesDetails=ze.createDetails(J.get("VOTSubtitlesDesign")),this.votSettingsDialog.bodyContainer.appendChild(this.votSubtitlesDetails.container),this.votProxyHeader=ze.createHeader(J.get("proxySettings")),this.votSettingsDialog.bodyContainer.appendChild(this.votProxyHeader),this.votM3u8ProxyHostTextfield=ze.createTextfield(J.get("VOTM3u8ProxyHost"),this.data?.m3u8ProxyHost,R),this.votSettingsDialog.bodyContainer.appendChild(this.votM3u8ProxyHostTextfield.container),this.votProxyWorkerHostTextfield=ze.createTextfield(J.get("VOTProxyWorkerHost"),this.data?.proxyWorkerHost,$),this.votSettingsDialog.bodyContainer.appendChild(this.votProxyWorkerHostTextfield.container),this.votAudioProxyCheckbox=ze.createCheckbox(J.get("VOTAudioProxy"),this.data?.audioProxy??!1),this.votSettingsDialog.bodyContainer.appendChild(this.votAudioProxyCheckbox.container),this.votNewAudioPlayerCheckbox=ze.createCheckbox(J.get("VOTNewAudioPlayer"),this.data?.newAudioPlayer??!1),this.audioContext||(this.votNewAudioPlayerCheckbox.input.disabled=!0,this.votNewAudioPlayerCheckbox.container.title=J.get("VOTNeedWebAudioAPI")),this.votSettingsDialog.bodyContainer.appendChild(this.votNewAudioPlayerCheckbox.container),this.votOnlyBypassMediaCSPCheckbox=ze.createCheckbox(J.get("VOTOnlyBypassMediaCSP")+(this.site.needBypassCSP?` (${J.get("VOTMediaCSPEnabledOnSite")})`:""),this.data?.onlyBypassMediaCSP??!1),this.votOnlyBypassMediaCSPCheckbox.container.classList.add("vot-checkbox-sub"),this.audioContext||(this.votOnlyBypassMediaCSPCheckbox.container.title=J.get("VOTNeedWebAudioAPI")),this.votOnlyBypassMediaCSPCheckbox.input.disabled=!this.data.newAudioPlayer&&this.audioContext,this.data.newAudioPlayer||(this.votOnlyBypassMediaCSPCheckbox.container.hidden=!0),this.votSettingsDialog.bodyContainer.appendChild(this.votOnlyBypassMediaCSPCheckbox.container),this.votAboutHeader=ze.createHeader(J.get("about")),this.votSettingsDialog.bodyContainer.appendChild(this.votAboutHeader),this.votLanguageSelect=ze.createVOTSelect(J.get("langs")[j.syncGet("locale-lang-override","auto")],J.get("VOTMenuLanguage"),wo(Y,j.syncGet("locale-lang-override","auto")),{onSelectCb:async t=>{await j.set("locale-lang-override",t.target.dataset.votValue)},labelElement:ze.createVOTSelectLabel(J.get("VOTMenuLanguage"))}),this.votSettingsDialog.bodyContainer.appendChild(this.votLanguageSelect.container),this.votShowPiPButtonCheckbox=ze.createCheckbox(J.get("VOTShowPiPButton"),this.data?.showPiPButton??!1),this.votShowPiPButtonCheckbox.container.hidden=!X(),this.votSettingsDialog.bodyContainer.appendChild(this.votShowPiPButtonCheckbox.container),this.votVersionInfo=ze.createInformation(`${J.get("VOTVersion")}:`,GM_info.script.version),this.votSettingsDialog.bodyContainer.appendChild(this.votVersionInfo.container),this.votAuthorsInfo=ze.createInformation(`${J.get("VOTAuthors")}:`,GM_info.script.author),this.votSettingsDialog.bodyContainer.appendChild(this.votAuthorsInfo.container),this.votLoaderInfo=ze.createInformation(`${J.get("VOTLoader")}:`,`${GM_info.scriptHandler} v${GM_info.version}`),this.votSettingsDialog.bodyContainer.appendChild(this.votLoaderInfo.container),this.votBrowserInfo=ze.createInformation(`${J.get("VOTBrowser")}:`,`${yo.browser.name} ${yo.browser.version} (${yo.os.name} ${yo.os.version})`),this.votSettingsDialog.bodyContainer.appendChild(this.votBrowserInfo.container),this.votLocaleInfo=ze.createInformation(`${J.get("VOTLocaleHash")}:`,jt`${this.data.localeHash}
(${J.get("VOTUpdatedAt")} - ${new Date(1e3*this.data.localeUpdatedAt).toLocaleString()})`),this.votSettingsDialog.bodyContainer.appendChild(this.votLocaleInfo.container),this.votUpdateLocaleFilesButton=ze.createOutlinedButton(J.get("VOTUpdateLocaleFiles")),this.votSettingsDialog.bodyContainer.appendChild(this.votUpdateLocaleFilesButton),this.votResetSettingsButton=ze.createButton(J.get("resetSettings")),this.votSettingsDialog.bodyContainer.appendChild(this.votResetSettingsButton)}async handleTranslationBtnClick(){if(N.log("[click translationBtn]",this.audioPlayer,this.audioPlayer.player),this.audioPlayer.player.src)return N.log("[click translationBtn] audio.src is not empty"),void this.stopTranslate();if(this.hls.url)return N.log("[click translationBtn] hls is not empty"),void this.stopTranslate();try{if(N.log("[click translationBtn] trying execute translation"),!this.videoData.videoId)throw new mt("VOTNoVideoIDFound");"vk"===this.site.host&&"clips"===this.site.additionalData&&(this.videoData=await this.getVideoData()),await this.translateExecutor(this.videoData.videoId)}catch(t){console.error("[VOT]",t),"VOTLocalizedError"===t?.name?this.transformBtn("error",t.localizedMessage):this.transformBtn("error",t?.message)}}initUIEvents(){this.votButton.translateButton.addEventListener("click",(async()=>{await this.handleTranslationBtnClick()})),this.votButton.pipButton.addEventListener("click",(()=>{(async()=>{this.video!==document.pictureInPictureElement?await this.video.requestPictureInPicture():await document.exitPictureInPicture()})()})),this.votButton.menuButton.addEventListener("click",(()=>{this.votMenu.container.hidden=!this.votMenu.container.hidden})),this.votButton.container.addEventListener("mousedown",(()=>{this.dragging=!0})),this.container.addEventListener("mouseup",(()=>{this.dragging=!1})),this.container.addEventListener("mousemove",(async t=>{if(this.dragging){t.preventDefault();const e=t.clientX/this.container.clientWidth*100,o=this.container.clientWidth>550,i=e<=44?"left":e>=66?"right":"default";this.data.buttonPos=o?i:"default",this.votButton.container.dataset.direction="default"===this.data.buttonPos?"row":"column",this.votButton.container.dataset.position=this.data.buttonPos,this.votMenu.container.dataset.position=this.data.buttonPos,o&&await j.set("buttonPos",this.data.buttonPos)}})),this.votDownloadButton.addEventListener("click",(async()=>{if(!this.downloadTranslationUrl)return;if(!this.data.downloadWithName)return window.open(this.downloadTranslationUrl,"_blank").focus();const t=document.querySelector("#vot-loader-download"),e=getComputedStyle(this.votMenu.container).getPropertyValue("--vot-primary-rgb"),o=ze.animateLoader(t,e),i=await it(this.downloadTranslationUrl),a=i.body.getReader(),n=+i.headers.get("Content-Length");let r=0;const s=[];for(;;){const{done:t,value:e}=await a.read();if(t)break;s.push(e),r+=e.length,o(Math.round(r/n*100))}ze.afterAnimateLoader(t,e);const l=new Blob(s),d=ot(this.videoData.title??this.videoData.videoId),u=await l.arrayBuffer(),c=new ye(u);c.setFrame("TIT2",d),c.addTag(),et(c.getBlob(),`${d}.mp3`)})),this.votDownloadSubtitlesButton.addEventListener("click",(async()=>{const t=this.data.subtitlesDownloadFormat,e=Tt(this.yandexSubtitles,t);et(new Blob(["json"===t?JSON.stringify(e):e],{type:"text/plain"}),`${this.data.downloadWithName?ot(this.videoData.title??this.videoData.videoId):`subtitles_${this.videoData.videoId}`}.${t}`)})),this.votSettingsButton.addEventListener("click",(()=>{this.votSettingsDialog.container.hidden=!this.votSettingsDialog.container.hidden,(document.fullscreenElement||document.webkitFullscreenElement)&&(document.webkitExitFullscreen&&document.webkitExitFullscreen(),document.exitFullscreen&&document.exitFullscreen())})),this.votVideoVolumeSlider.input.addEventListener("input",(t=>{const e=Number(t.target.value);this.votVideoVolumeSlider.label.querySelector("strong").textContent=`${e}%`,this.setVideoVolume(e/100),this.data.syncVolume&&this.syncVolumeWrapper("video",e)})),this.votVideoTranslationVolumeSlider.input.addEventListener("input",(t=>{(async()=>{this.data.defaultVolume=Number(t.target.value),await j.set("defaultVolume",this.data.defaultVolume),this.votVideoTranslationVolumeSlider.label.querySelector("strong").textContent=`${this.data.defaultVolume}%`,this.audioPlayer.player.volume=this.data.defaultVolume/100,this.data.syncVolume&&(this.syncVolumeWrapper("translation",this.data.defaultVolume),["youtube","googledrive"].includes(this.site.host)&&"mobile"!==this.site.additionalData&&this.setVideoVolume(this.tempOriginalVolume/100))})()}));{this.votAutoTranslateCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.autoTranslate=Number(t.target.checked),await Promise.all([j.set("autoTranslate",this.data.autoTranslate),this.autoTranslate()]),N.log("autoTranslate value changed. New value: ",this.data.autoTranslate)})()})),this.votDontTranslateYourLangSelect.labelElement.addEventListener("change",(t=>{(async()=>{this.data.dontTranslateYourLang=Number(t.target.checked),await j.set("dontTranslateYourLang",this.data.dontTranslateYourLang),N.log("dontTranslateYourLang value changed. New value: ",this.data.dontTranslateYourLang)})()}));const t=async t=>{await j.set("hotkeyButton",t),this.data.hotkeyButton=t,this.changehotkeyButton.textContent=xo(t)},e=o=>{const i="Escape"===o.code?null:o.code;t(i),document.removeEventListener("keydown",e)};this.changehotkeyButton.addEventListener("click",(()=>{this.changehotkeyButton.textContent=J.get("VOTPressNewHotkey"),document.addEventListener("keydown",e)})),this.votAutoSetVolumeCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.autoSetVolumeYandexStyle=Number(t.target.checked),await j.set("autoSetVolumeYandexStyle",this.data.autoSetVolumeYandexStyle),N.log("autoSetVolumeYandexStyle value changed. New value: ",this.data.autoSetVolumeYandexStyle)})()})),this.votAutoSetVolumeSlider.input.addEventListener("input",(t=>{(async()=>{const e=Number(t.target.value);this.data.autoVolume=(e/100).toFixed(2),await j.set("autoVolume",this.data.autoVolume),this.votAutoSetVolumeSlider.label.querySelector("strong").textContent=`${e}%`})()})),this.votShowVideoSliderCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.showVideoSlider=Number(t.target.checked),await j.set("showVideoSlider",this.data.showVideoSlider),N.log("showVideoSlider value changed. New value: ",this.data.showVideoSlider),this.votVideoVolumeSlider.container.hidden=1!==this.data.showVideoSlider||"success"!==this.votButton.container.dataset.status})()})),this.votAudioBoosterCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.audioBooster=Number(t.target.checked),await j.set("audioBooster",this.data.audioBooster),N.log("audioBooster value changed. New value: ",this.data.audioBooster);const e=this.votVideoTranslationVolumeSlider.input.value;this.votVideoTranslationVolumeSlider.input.max=this.data.audioBooster?900:100,this.data.audioBooster||(this.votVideoTranslationVolumeSlider.input.value=e>100?100:e,this.votVideoTranslationVolumeSlider.input.dispatchEvent(new Event("input")))})()})),this.votSyncVolumeCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.syncVolume=Number(t.target.checked),await j.set("syncVolume",this.data.syncVolume),N.log("syncVolume value changed. New value: ",this.data.syncVolume)})()})),this.votDownloadWithNameCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.downloadWithName=Number(t.target.checked),await j.set("downloadWithName",this.data.downloadWithName),N.log("downloadWithName value changed. New value: ",this.data.downloadWithName)})()})),this.votTranslationServiceSelect.labelElement.addEventListener("change",(t=>{(async()=>{this.data.translateAPIErrors=Number(t.target.checked),await j.set("translateAPIErrors",this.data.translateAPIErrors),N.log("translateAPIErrors value changed. New value: ",this.data.translateAPIErrors)})()})),this.votSubtitlesDetails.container.addEventListener("click",(()=>{this.votSubtitlesDialog=ze.createDialog(J.get("VOTSubtitlesDesign")),this.votSubtitlesDialog.container.classList.add("vot-dialog-temp"),this.votSubtitlesDialog.container.hidden=!1,this.votSubtitlesDialog.backdrop.onclick=this.votSubtitlesDialog.closeButton.onclick=()=>{this.votSubtitlesDialog.container.remove()},this.votSubtitlesHighlightWordsCheckbox=ze.createCheckbox(J.get("VOTHighlightWords"),this.data?.highlightWords??!1),this.votSubtitlesDialog.bodyContainer.appendChild(this.votSubtitlesHighlightWordsCheckbox.container),this.votSubtitlesDownloadFormatSelect=ze.createVOTSelect(this.data.subtitlesDownloadFormat.toUpperCase(),J.get("VOTSubtitlesDownloadFormat"),wo(dt,this.data.subtitlesDownloadFormat),{onSelectCb:async t=>{this.data.subtitlesDownloadFormat=t.target.dataset.votValue,await j.set("subtitlesDownloadFormat",this.data.subtitlesDownloadFormat)},labelElement:ze.createVOTSelectLabel(J.get("VOTSubtitlesDownloadFormat"))}),this.votSubtitlesDialog.bodyContainer.appendChild(this.votSubtitlesDownloadFormatSelect.container),this.votSubtitlesMaxLengthSlider=ze.createSlider(jt`${J.get("VOTSubtitlesMaxLength")}: + ${new Date(1e3*this.data.localeUpdatedAt).toLocaleString()})`),this.votSettingsDialog.bodyContainer.appendChild(this.votLocaleInfo.container),this.votUpdateLocaleFilesButton=ze.createOutlinedButton(J.get("VOTUpdateLocaleFiles")),this.votSettingsDialog.bodyContainer.appendChild(this.votUpdateLocaleFilesButton),this.votResetSettingsButton=ze.createButton(J.get("resetSettings")),this.votSettingsDialog.bodyContainer.appendChild(this.votResetSettingsButton)}async handleTranslationBtnClick(){if(N.log("[click translationBtn]",this.audioPlayer,this.audioPlayer.player),this.audioPlayer.player.src)return N.log("[click translationBtn] audio.src is not empty",this.audioPlayer.player.src),void this.stopTranslate();if(this.hls.url)return N.log("[click translationBtn] hls is not empty",this.hls.url),void this.stopTranslate();try{if(N.log("[click translationBtn] trying execute translation"),!this.videoData.videoId)throw new mt("VOTNoVideoIDFound");"vk"===this.site.host&&"clips"===this.site.additionalData&&(this.videoData=await this.getVideoData()),await this.translateExecutor(this.videoData.videoId)}catch(t){console.error("[VOT]",t),"VOTLocalizedError"===t?.name?this.transformBtn("error",t.localizedMessage):this.transformBtn("error",t?.message)}}initUIEvents(){this.votButton.translateButton.addEventListener("click",(async()=>{await this.handleTranslationBtnClick()})),this.votButton.pipButton.addEventListener("click",(()=>{(async()=>{this.video!==document.pictureInPictureElement?await this.video.requestPictureInPicture():await document.exitPictureInPicture()})()})),this.votButton.menuButton.addEventListener("click",(()=>{this.votMenu.container.hidden=!this.votMenu.container.hidden})),this.votButton.container.addEventListener("mousedown",(()=>{this.dragging=!0})),this.container.addEventListener("mouseup",(()=>{this.dragging=!1})),this.container.addEventListener("mousemove",(async t=>{if(this.dragging){t.preventDefault();const e=t.clientX/this.container.clientWidth*100,o=this.container.clientWidth>550,i=e<=44?"left":e>=66?"right":"default";this.data.buttonPos=o?i:"default",this.votButton.container.dataset.direction="default"===this.data.buttonPos?"row":"column",this.votButton.container.dataset.position=this.data.buttonPos,this.votMenu.container.dataset.position=this.data.buttonPos,o&&await j.set("buttonPos",this.data.buttonPos)}})),this.votDownloadButton.addEventListener("click",(async()=>{if(!this.downloadTranslationUrl)return;if(!this.data.downloadWithName)return window.open(this.downloadTranslationUrl,"_blank").focus();const t=document.querySelector("#vot-loader-download"),e=getComputedStyle(this.votMenu.container).getPropertyValue("--vot-primary-rgb"),o=ze.animateLoader(t,e),i=await it(this.downloadTranslationUrl),a=i.body.getReader(),n=+i.headers.get("Content-Length");let r=0;const s=[];for(;;){const{done:t,value:e}=await a.read();if(t)break;s.push(e),r+=e.length,o(Math.round(r/n*100))}ze.afterAnimateLoader(t,e);const l=new Blob(s),d=ot(this.videoData.title??this.videoData.videoId),u=await l.arrayBuffer(),c=new ye(u);c.setFrame("TIT2",d),c.addTag(),et(c.getBlob(),`${d}.mp3`)})),this.votDownloadSubtitlesButton.addEventListener("click",(async()=>{const t=this.data.subtitlesDownloadFormat,e=Tt(this.yandexSubtitles,t);et(new Blob(["json"===t?JSON.stringify(e):e],{type:"text/plain"}),`${this.data.downloadWithName?ot(this.videoData.title??this.videoData.videoId):`subtitles_${this.videoData.videoId}`}.${t}`)})),this.votSettingsButton.addEventListener("click",(()=>{this.votSettingsDialog.container.hidden=!this.votSettingsDialog.container.hidden,(document.fullscreenElement||document.webkitFullscreenElement)&&(document.webkitExitFullscreen&&document.webkitExitFullscreen(),document.exitFullscreen&&document.exitFullscreen())})),this.votVideoVolumeSlider.input.addEventListener("input",(t=>{const e=Number(t.target.value);this.votVideoVolumeSlider.label.querySelector("strong").textContent=`${e}%`,this.setVideoVolume(e/100),this.data.syncVolume&&this.syncVolumeWrapper("video",e)})),this.votVideoTranslationVolumeSlider.input.addEventListener("input",(t=>{(async()=>{this.data.defaultVolume=Number(t.target.value),await j.set("defaultVolume",this.data.defaultVolume),this.votVideoTranslationVolumeSlider.label.querySelector("strong").textContent=`${this.data.defaultVolume}%`,this.audioPlayer.player.volume=this.data.defaultVolume/100,this.data.syncVolume&&(this.syncVolumeWrapper("translation",this.data.defaultVolume),["youtube","googledrive"].includes(this.site.host)&&"mobile"!==this.site.additionalData&&this.setVideoVolume(this.tempOriginalVolume/100))})()}));{this.votAutoTranslateCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.autoTranslate=Number(t.target.checked),await Promise.all([j.set("autoTranslate",this.data.autoTranslate),this.autoTranslate()]),N.log("autoTranslate value changed. New value: ",this.data.autoTranslate)})()})),this.votDontTranslateYourLangSelect.labelElement.addEventListener("change",(t=>{(async()=>{this.data.dontTranslateYourLang=Number(t.target.checked),await j.set("dontTranslateYourLang",this.data.dontTranslateYourLang),N.log("dontTranslateYourLang value changed. New value: ",this.data.dontTranslateYourLang)})()}));const t=async t=>{await j.set("hotkeyButton",t),this.data.hotkeyButton=t,this.changehotkeyButton.textContent=xo(t)},e=o=>{const i="Escape"===o.code?null:o.code;t(i),document.removeEventListener("keydown",e)};this.changehotkeyButton.addEventListener("click",(()=>{this.changehotkeyButton.textContent=J.get("VOTPressNewHotkey"),document.addEventListener("keydown",e)})),this.votAutoSetVolumeCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.autoSetVolumeYandexStyle=Number(t.target.checked),await j.set("autoSetVolumeYandexStyle",this.data.autoSetVolumeYandexStyle),N.log("autoSetVolumeYandexStyle value changed. New value: ",this.data.autoSetVolumeYandexStyle)})()})),this.votAutoSetVolumeSlider.input.addEventListener("input",(t=>{(async()=>{const e=Number(t.target.value);this.data.autoVolume=(e/100).toFixed(2),await j.set("autoVolume",this.data.autoVolume),this.votAutoSetVolumeSlider.label.querySelector("strong").textContent=`${e}%`})()})),this.votShowVideoSliderCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.showVideoSlider=Number(t.target.checked),await j.set("showVideoSlider",this.data.showVideoSlider),N.log("showVideoSlider value changed. New value: ",this.data.showVideoSlider),this.votVideoVolumeSlider.container.hidden=1!==this.data.showVideoSlider||"success"!==this.votButton.container.dataset.status})()})),this.votAudioBoosterCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.audioBooster=Number(t.target.checked),await j.set("audioBooster",this.data.audioBooster),N.log("audioBooster value changed. New value: ",this.data.audioBooster);const e=this.votVideoTranslationVolumeSlider.input.value;this.votVideoTranslationVolumeSlider.input.max=this.data.audioBooster?900:100,this.data.audioBooster||(this.votVideoTranslationVolumeSlider.input.value=e>100?100:e,this.votVideoTranslationVolumeSlider.input.dispatchEvent(new Event("input")))})()})),this.votSyncVolumeCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.syncVolume=Number(t.target.checked),await j.set("syncVolume",this.data.syncVolume),N.log("syncVolume value changed. New value: ",this.data.syncVolume)})()})),this.votDownloadWithNameCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.downloadWithName=Number(t.target.checked),await j.set("downloadWithName",this.data.downloadWithName),N.log("downloadWithName value changed. New value: ",this.data.downloadWithName)})()})),this.votTranslationServiceSelect.labelElement.addEventListener("change",(t=>{(async()=>{this.data.translateAPIErrors=Number(t.target.checked),await j.set("translateAPIErrors",this.data.translateAPIErrors),N.log("translateAPIErrors value changed. New value: ",this.data.translateAPIErrors)})()})),this.votSubtitlesDetails.container.addEventListener("click",(()=>{this.votSubtitlesDialog=ze.createDialog(J.get("VOTSubtitlesDesign")),this.votSubtitlesDialog.container.classList.add("vot-dialog-temp"),this.votSubtitlesDialog.container.hidden=!1,this.votSubtitlesDialog.backdrop.onclick=this.votSubtitlesDialog.closeButton.onclick=()=>{this.votSubtitlesDialog.container.remove()},this.votSubtitlesHighlightWordsCheckbox=ze.createCheckbox(J.get("VOTHighlightWords"),this.data?.highlightWords??!1),this.votSubtitlesDialog.bodyContainer.appendChild(this.votSubtitlesHighlightWordsCheckbox.container),this.votSubtitlesDownloadFormatSelect=ze.createVOTSelect(this.data.subtitlesDownloadFormat.toUpperCase(),J.get("VOTSubtitlesDownloadFormat"),wo(dt,this.data.subtitlesDownloadFormat),{onSelectCb:async t=>{this.data.subtitlesDownloadFormat=t.target.dataset.votValue,await j.set("subtitlesDownloadFormat",this.data.subtitlesDownloadFormat)},labelElement:ze.createVOTSelectLabel(J.get("VOTSubtitlesDownloadFormat"))}),this.votSubtitlesDialog.bodyContainer.appendChild(this.votSubtitlesDownloadFormatSelect.container),this.votSubtitlesMaxLengthSlider=ze.createSlider(jt`${J.get("VOTSubtitlesMaxLength")}: ${this.data?.subtitlesMaxLength??300}`,this.data?.subtitlesMaxLength??300,50,300),this.votSubtitlesDialog.bodyContainer.appendChild(this.votSubtitlesMaxLengthSlider.container),this.votSubtitlesFontSizeSlider=ze.createSlider(jt`${J.get("VOTSubtitlesFontSize")}: ${this.data?.subtitlesFontSize??20}`,this.data?.subtitlesFontSize??20,8,50),this.votSubtitlesDialog.bodyContainer.appendChild(this.votSubtitlesFontSizeSlider.container),this.votSubtitlesOpacitySlider=ze.createSlider(jt`${J.get("VOTSubtitlesOpacity")}: - ${this.data?.subtitlesOpacity??20}`,this.data?.subtitlesOpacity??20,0,100),this.votSubtitlesDialog.bodyContainer.appendChild(this.votSubtitlesOpacitySlider.container),this.votSubtitlesHighlightWordsCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.highlightWords=Number(t.target.checked),await j.set("highlightWords",this.data.highlightWords),N.log("highlightWords value changed. New value: ",this.data.highlightWords),this.subtitlesWidget.setHighlightWords(this.data.highlightWords)})()})),this.votSubtitlesMaxLengthSlider.input.addEventListener("input",(t=>{(async()=>{this.data.subtitlesMaxLength=Number(t.target.value),await j.set("subtitlesMaxLength",this.data.subtitlesMaxLength),this.votSubtitlesMaxLengthSlider.label.querySelector("strong").textContent=`${this.data.subtitlesMaxLength}`,this.subtitlesWidget.setMaxLength(this.data.subtitlesMaxLength)})()})),this.votSubtitlesFontSizeSlider.input.addEventListener("input",(t=>{(async()=>{this.data.subtitlesFontSize=Number(t.target.value),await j.set("subtitlesFontSize",this.data.subtitlesFontSize),this.votSubtitlesFontSizeSlider.label.querySelector("strong").textContent=`${this.data.subtitlesFontSize}`,this.subtitlesWidget.setFontSize(this.data.subtitlesFontSize)})()})),this.votSubtitlesOpacitySlider.input.addEventListener("input",(t=>{(async()=>{this.data.subtitlesOpacity=Number(t.target.value),await j.set("subtitlesOpacity",this.data.subtitlesOpacity),this.votSubtitlesOpacitySlider.label.querySelector("strong").textContent=`${this.data.subtitlesOpacity}`,this.subtitlesWidget.setOpacity(this.data.subtitlesOpacity)})()})),document.documentElement.appendChild(this.votSubtitlesDialog.container)})),this.votShowPiPButtonCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.showPiPButton=Number(t.target.checked),await j.set("showPiPButton",this.data.showPiPButton),N.log("showPiPButton value changed. New value: ",this.data.showPiPButton),this.votButton.pipButton.hidden=!X()||!this.data.showPiPButton,this.votButton.separator2.hidden=!X()||!this.data.showPiPButton})()})),this.votM3u8ProxyHostTextfield.input.addEventListener("change",(t=>{(async()=>{this.data.m3u8ProxyHost=t.target.value||R,await j.set("m3u8ProxyHost",this.data.m3u8ProxyHost),N.log("m3u8ProxyHost value changed. New value: ",this.data.m3u8ProxyHost)})()})),this.votProxyWorkerHostTextfield.input.addEventListener("change",(t=>{(async()=>{this.data.proxyWorkerHost=t.target.value||$,await j.set("proxyWorkerHost",this.data.proxyWorkerHost),N.log("proxyWorkerHost value changed. New value: ",this.data.proxyWorkerHost),this.data.translateProxyEnabled&&(this.votClient.host=this.data.proxyWorkerHost)})()})),this.votAudioProxyCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.audioProxy=Number(t.target.checked),await j.set("audioProxy",this.data.audioProxy),N.log("audioProxy value changed. New value: ",this.data.audioProxy)})()})),this.votOnlyBypassMediaCSPCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.onlyBypassMediaCSP=Number(t.target.checked),await j.set("onlyBypassMediaCSP",this.data.onlyBypassMediaCSP),N.log("onlyBypassMediaCSP value changed. New value: ",this.data.onlyBypassMediaCSP),this.stopTranslate(),this.createPlayer()})()})),this.votNewAudioPlayerCheckbox.input.addEventListener("change",(t=>{(async()=>{const e=t.target.checked;this.data.newAudioPlayer=Number(e),await j.set("newAudioPlayer",this.data.newAudioPlayer),N.log("newAudioPlayer value changed. New value: ",this.data.newAudioPlayer),this.stopTranslate(),this.createPlayer(),this.votOnlyBypassMediaCSPCheckbox.input.disabled=this.votOnlyBypassMediaCSPCheckbox.container.hidden=!e})()})),this.votUpdateLocaleFilesButton.addEventListener("click",(()=>{(async()=>{await j.set("locale-hash",""),await J.update(!0),window.location.reload()})()})),this.votResetSettingsButton.addEventListener("click",(()=>{(async()=>{J.reset();const t=await j.list();for(let e=0;e{this.extraEvents.push({element:t,event:e,handler:o}),t.addEventListener(e,o)},e=(e,o,i)=>{for(const a of o)t(e,a,i)};if(this.resizeObserver=new ResizeObserver((t=>{for(let e=0;e550;this.votButton.container.dataset.position=this.votMenu.container.dataset.position=e?this.data?.buttonPos:"default",this.votButton.container.dataset.direction=this.data?.buttonPos&&"default"!==this.data?.buttonPos&&e?"column":"row"})),this.resizeObserver.observe(this.video),this.votMenu.container.setAttribute("style",`--vot-container-height: ${this.video.getBoundingClientRect().height}px`),["youtube","googledrive"].includes(this.site.host)&&"mobile"!==this.site.additionalData){this.syncVolumeObserver=new MutationObserver((t=>{if(this.audioPlayer.player.src&&this.data.syncVolume)for(let e=0;e{const e=t.target,o=this.votButton.container,i=this.votMenu.container,a=this.container,n=this.votSettingsDialog.container,r=document.querySelector(".vot-dialog-temp"),s=o.contains(e),l=i.contains(e),d=a.contains(e),u=n.contains(e),c=r?.contains(e)??!1;N.log(`[document click] ${s} ${l} ${d} ${u} ${c}`),s||l||u||c||(d||this.logout(0),this.votMenu.container.hidden=!0)})),document.addEventListener("keydown",(async t=>{const e=t.code,o=document.activeElement;["input","textarea"].includes(o.tagName.toLowerCase())||o.isContentEditable||e!==this.data.hotkeyButton||await this.handleTranslationBtnClick()}));let o=this.site.eventSelector?document.querySelector(this.site.eventSelector):this.container;o&&e(o,["mousemove","mouseout"],this.resetTimer),t(this.votButton.container,"mousemove",this.changeOpacityOnEvent),t(this.votMenu.container,"mousemove",this.changeOpacityOnEvent),e(document,["touchstart","touchmove","touchend"],this.changeOpacityOnEvent),t(this.votButton.container,"mousedown",(t=>{t.stopImmediatePropagation()})),t(this.votMenu.container,"mousedown",(t=>{t.stopImmediatePropagation()})),"youtube"===this.site.host&&(this.container.draggable=!1),"googledrive"===this.site.host&&(this.container.style.height="100%"),t(this.video,"canplay",(async()=>{"rutube"===this.site.host&&this.video.src||await this.setCanPlay()})),t(this.video,"emptied",(async()=>{this.video.src&&await pt(this.site,this.video)===this.videoData.videoId||(N.log("lipsync mode is emptied"),this.videoData="",this.stopTranslation())})),["rutube","ok"].includes(this.site.host)||t(this.video,"volumechange",(()=>{this.syncVideoVolumeSlider()})),"youtube"!==this.site.host||this.site.additionalData||t(document,"yt-page-data-updated",(async()=>{N.log("yt-page-data-updated"),window.location.pathname.includes("/shorts/")&&await this.setCanPlay()}))}async setCanPlay(){await pt(this.site,this.video)!==this.videoData.videoId&&(await this.handleSrcChanged(),await this.autoTranslate(),N.log("lipsync mode is canplay"))}logout(t){this.votMenu.container.hidden&&(this.votButton.container.style.opacity=t)}resetTimer=()=>{clearTimeout(this.timer),this.logout(1),this.timer=setTimeout((()=>{this.logout(0)}),1e3)};changeOpacityOnEvent=t=>{clearTimeout(this.timer),this.logout(1),t.stopPropagation()};async changeSubtitlesLang(t){if(N.log("[onchange] subtitles",t),this.votSubtitlesSelect.setSelected(t),"disabled"===t)this.votSubtitlesSelect.setTitle(J.get("VOTSubtitlesDisabled")),this.subtitlesWidget.setContent(null),this.votDownloadSubtitlesButton.hidden=!0,this.yandexSubtitles=null;else{const e=this.subtitlesList.at(parseInt(t));if(1===this.data.audioProxy&&e.url.startsWith("https://brosubs.s3-private.mds.yandex.net/vtrans/")){const t=e.url.replace("https://brosubs.s3-private.mds.yandex.net/vtrans/","");e.url=`https://${this.data.proxyWorkerHost}/video-subtitles/subtitles-proxy/${t}`,console.log(`[VOT] Subs proxied via ${e.url}`)}this.yandexSubtitles=await Me(e),this.subtitlesWidget.setContent(this.yandexSubtitles),this.votDownloadSubtitlesButton.hidden=!1}}async updateSubtitlesLangSelect(){const t=[{label:J.get("VOTSubtitlesDisabled"),value:"disabled",selected:!0,disabled:!1},...this.subtitlesList.map(((t,e)=>({label:(J.get("langs")[t.language]??t.language.toUpperCase())+(t.translatedFromLanguage?` ${J.get("VOTTranslatedFrom")} ${J.get("langs")[t.translatedFromLanguage]??t.translatedFromLanguage.toUpperCase()}`:"")+("yandex"!==t.source?`, ${window.location.hostname}`:"")+(t.isAutoGenerated?` (${J.get("VOTAutogenerated")})`:""),value:e,selected:!1,disabled:!1})))];this.votSubtitlesSelect.updateItems(t),await this.changeSubtitlesLang(t[0].value)}async updateSubtitles(){if(await this.changeSubtitlesLang("disabled"),!this.videoData.videoId)return console.error(`[VOT] ${J.getDefault("VOTNoVideoIDFound")}`),this.subtitlesList=[],this.subtitlesListVideoId=null,this.votButton.container.hidden=!0,void await this.updateSubtitlesLangSelect();if(this.votButton.container.hidden=!1,this.subtitlesListVideoId!==this.videoData.videoId){try{this.subtitlesList=await Ee(this.votClient,this.videoData)}catch(t){N.log("Error with yandex server, try auto-fix...",t),this.votOpts={fetchFn:it,hostVOT:D,host:this.data.proxyWorkerHost},this.votClient=new yt(this.votOpts),this.subtitlesList=await Ee(this.votClient,this.videoData),await j.set("translateProxyEnabled",1)}this.subtitlesList?this.subtitlesListVideoId=this.videoData.videoId:await this.changeSubtitlesLang("disabled"),await this.updateSubtitlesLangSelect()}}getVideoVolume(){let t=this.video?.volume;return["youtube","googledrive"].includes(this.site.host)&&(t=_e.getVideoVolume()??t),t}setVideoVolume(t){if(["youtube","googledrive"].includes(this.site.host)){if(_e.setVideoVolume(t))return this}return this.video.volume=t,this}isMuted(){return["youtube","googledrive"].includes(this.site.host)?_e.isMuted():this.video?.muted}syncVideoVolumeSlider(){const t=this.isMuted()?0:100*this.getVideoVolume(),e=Math.round(t);this.votVideoVolumeSlider.input.value=e,this.votVideoVolumeSlider.label.querySelector("strong").textContent=`${e}%`,ze.updateSlider(this.votVideoVolumeSlider.input),1===this.data.syncVolume&&(this.tempOriginalVolume=Number(e))}setSelectMenuValues(t,e){this.votTranslationLanguageSelect.fromSelect.setTitle(J.get("langs")[t]),this.votTranslationLanguageSelect.toSelect.setTitle(J.get("langs")[e]),this.votTranslationLanguageSelect.fromSelect.setSelected(t),this.votTranslationLanguageSelect.toSelect.setSelected(e),console.log(`[VOT] Set translation from ${t} to ${e}`),this.videoData.detectedLanguage=t,this.videoData.responseLanguage=e}syncVolumeWrapper(t,e){const o="translation"===t?this.votVideoVolumeSlider:this.votVideoTranslationVolumeSlider,i=Number(o.input.value),a=function(t,e,o,i){let a=e;return e>i?(a=o+(e-i),a=a>100?100:Math.max(a,0),t.volume=a/100):e100?100:Math.max(a,0),t.volume=a/100),a}("translation"===t?this.video:this.audioPlayer.player,e,i,"translation"===t?this.tempVolume:this.tempOriginalVolume);o.input.value=a,o.label.querySelector("strong").textContent=`${a}%`,ze.updateSlider(o.input),this.tempOriginalVolume="translation"===t?a:e,this.tempVolume="translation"===t?e:a}async getVideoData(){const{duration:t,url:e,videoId:o,host:i,title:a,translationHelp:n,detectedLanguage:r,subtitles:s}=await gt(this.site,this.video),l={translationHelp:n??null,isStream:!1,duration:this.video?.duration||t||P.defaultDuration,videoId:o,url:e,host:i,detectedLanguage:r??this.translateFromLang,responseLanguage:this.translateToLang,subtitles:s,title:a};if("youtube"===this.site.host){const t=await _e.getVideoData();l.isStream=t.isLive,t.title&&(l.detectedLanguage=t.detectedLanguage,l.title=t.localizedTitle)}else if(["rutube","ok.ru","mail_ru"].includes(this.site.host))l.detectedLanguage="ru";else if("youku"===this.site.host)l.detectedLanguage="zh";else if("vk"===this.site.host){const t=document.getElementsByTagName("track")?.[0]?.srclang;l.detectedLanguage=t||"auto"}else"weverse"===this.site.host?l.detectedLanguage="ko":["bilibili","bitchute","rumble","peertube","dailymotion","trovo","yandexdisk","coursehunterLike","archive","nineanimetv","directlink"].includes(this.site.host)&&(l.detectedLanguage="auto");return l}videoValidator(){if(["youtube","ok.ru","vk"].includes(this.site.host)&&(N.log("VideoValidator videoData: ",this.videoData),1===this.data.dontTranslateYourLang&&this.videoData.detectedLanguage===this.data.dontTranslateLanguage))throw new mt("VOTDisableFromYourLang");if(!this.videoData.isStream&&this.videoData.duration>14400)throw new mt("VOTVideoIsTooLong");return!0}stopTranslate(){this.audioPlayer.player.removeVideoEvents(),this.audioPlayer.player.clear(),this.audioPlayer.player.src=void 0,this.votVideoVolumeSlider.container.hidden=!0,this.votVideoTranslationVolumeSlider.container.hidden=!0,this.votDownloadButton.hidden=!0,this.downloadTranslationUrl=null,this.transformBtn("none",J.get("translateVideo")),N.log(`Volume on start: ${this.volumeOnStart}`),this.volumeOnStart&&this.setVideoVolume(this.volumeOnStart),clearInterval(this.streamPing),clearTimeout(this.autoRetry),this.hls?.destroy(),this.hls=Q(),this.firstSyncVolume=!0}async translateExecutor(t){N.log("Run translateFunc",t),await this.translateFunc(t,this.videoData.isStream,this.videoData.detectedLanguage,this.videoData.responseLanguage,this.videoData.translationHelp)}async updateTranslationErrorMsg(t){const e=J.get("translationTake"),o=J.lang;if("VOTLocalizedError"===t?.name)this.transformBtn("error",t.localizedMessage);else if(t instanceof Error)this.transformBtn("error",t?.message);else if(1!==this.data.translateAPIErrors||t.includes(e)||"ru"===o)this.transformBtn("error",t);else{this.setLoadingBtn(!0);const e=await async function(t,e="",o="ru"){switch(await j.get("translationService",q)){case"yandex":{const i=e&&o?`${e}-${o}`:o;return await we.translate(t,i)}case"deepl":return await Se.translate(t,e,o);default:return t}}(t,"ru",o);this.transformBtn("error",e)}["Подготавливаем перевод","Видео передано в обработку","Ожидаем перевод видео","Загружаем переведенное аудио"].includes(t)&&this.setLoadingBtn(!0)}afterUpdateTranslation(t){this.votVideoVolumeSlider.container.hidden=1!==this.data.showVideoSlider||"success"!==this.votButton.container.dataset.status,this.votVideoTranslationVolumeSlider.container.hidden="success"!==this.votButton.container.dataset.status,1===this.data.autoSetVolumeYandexStyle&&(this.votVideoVolumeSlider.input.value=100*this.data.autoVolume,this.votVideoVolumeSlider.label.querySelector("strong").textContent=100*this.data.autoVolume+"%",ze.updateSlider(this.votVideoVolumeSlider.input)),this.votDownloadButton.hidden=!1,this.downloadTranslationUrl=t}async validateAudioUrl(t){try{const e=await it(t,{method:"HEAD",timeout:5e3});if(N.log("Test audio response",e),404!==e.status)return N.log("Valid audioUrl",t),t;N.log("Yandex returned not valid audio, trying to fix...");let o=await this.translateVideoImpl(this.videoData,this.videoData.detectedLanguage="auto",this.videoData.responseLanguage,this.videoData.translationHelp);this.setSelectMenuValues(this.videoData.detectedLanguage,this.videoData.responseLanguage),t=o.url,N.log("Fixed audio audioUrl",t)}catch(t){"Timeout"===t.message?(N.log("Request timed out. Handling timeout error..."),this.data.audioProxy=1,await j.set("audioProxy",1)):N.log("Test audio error:",t)}return t}async updateTranslation(t){if(this.cachedTranslation?.url!==this.audioPlayer.player.currentSrc&&(t=await this.validateAudioUrl(t)),1===this.data.audioProxy&&t.startsWith("https://vtrans.s3-private.mds.yandex.net/tts/prod/")){const e=t.replace("https://vtrans.s3-private.mds.yandex.net/tts/prod/","");t=`https://${this.data.proxyWorkerHost}/video-translation/audio-proxy/${e}`,console.log(`[VOT] Audio proxied via ${t}`)}this.audioPlayer.player.src!==t&&(this.audioPlayer.player.src=t);try{this.audioPlayer.init()}catch(t){t.message.includes("Failed to fetch audio file")?(this.videoHandler.data.audioProxy=1,await j.set("audioProxy",1)):this.videoHandler.transformBtn("error",t.message)}this.setupAudioSettings(),"twitter"===this.site.host&&document.querySelector('button[data-testid="app-bar-back"][role="button"]').addEventListener("click",this.stopTranslation),this.transformBtn("success",J.get("disableTranslate")),this.afterUpdateTranslation(t)}async translateFunc(t,e,o,i,a){if(console.log("[VOT] Video Data: ",this.videoData),N.log("Run videoValidator"),this.videoValidator(),this.setLoadingBtn(!0),this.volumeOnStart=this.getVideoVolume(),e){let t=await this.translateStreamImpl(this.videoData,o,i);if(!t)return void N.log("Skip translation");this.transformBtn("success",J.get("disableTranslate"));const e=this.setHLSSource(t.result.url);return"youtube"===this.site.host&&_e.videoSeek(this.video,10),this.setupAudioSettings(),this.video.src||this.video.currentSrc||this.video.srcObject?this.afterUpdateTranslation(e):this.stopTranslation()}if(this.cachedTranslation=this.videoTranslations.find((e=>e.videoId===t&&e.expires>at()&&e.from===o&&e.to===i)),this.cachedTranslation)return await this.updateTranslation(this.cachedTranslation.url),void N.log("[translateFunc] Cached translation was received");let n=await this.translateVideoImpl(this.videoData,o,i,a);N.log("[translateRes]",n),n?(await this.updateTranslation(n.url),this.subtitlesList.some((t=>"yandex"===t.source&&t.translatedFromLanguage===this.videoData.detectedLanguage&&t.language===this.videoData.responseLanguage))||(this.subtitlesList=await Ee(this.votClient,this.videoData),await this.updateSubtitlesLangSelect()),this.videoTranslations.push({videoId:t,from:o,to:i,url:this.downloadTranslationUrl,expires:at()+this.videoTranslationTTL})):N.log("Skip translation")}setupHLS(t){this.hls.on(Hls.Events.MEDIA_ATTACHED,(function(){N.log("audio and hls.js are now bound together !")})),this.hls.on(Hls.Events.MANIFEST_PARSED,(function(t){N.log("manifest loaded, found "+t?.levels?.length+" quality level")})),this.hls.loadSource(t),this.hls.attachMedia(this.audioPlayer.player.audio),this.hls.on(Hls.Events.ERROR,(function(t){if(t.fatal)switch(t.type){case Hls.ErrorTypes.MEDIA_ERROR:console.log("fatal media error encountered, try to recover"),this.hls.recoverMediaError();break;case Hls.ErrorTypes.NETWORK_ERROR:console.error("fatal network error encountered",t);break;default:this.hls.destroy()}})),N.log(this.hls)}setHLSSource(t){const e=`https://${this.data.m3u8ProxyHost}/?all=yes&origin=${encodeURIComponent("https://strm.yandex.ru")}&referer=${encodeURIComponent("https://strm.yandex.ru")}&url=${encodeURIComponent(t)}`;if(this.hls)this.setupHLS(e);else{if(!this.audioPlayer.player.audio.canPlayType("application/vnd.apple.mpegurl"))throw new mt("audioFormatNotSupported");this.audioPlayer.player.src=e}return e}setupAudioSettings(){"number"==typeof this.data.defaultVolume&&(this.audioPlayer.player.volume=this.data.defaultVolume/100),"number"==typeof this.data.autoSetVolumeYandexStyle&&this.data.autoSetVolumeYandexStyle&&this.setVideoVolume(this.data.autoVolume)}stopTranslation=()=>{this.stopTranslate(),this.syncVideoVolumeSlider()};async handleSrcChanged(){N.log("[VideoHandler] src changed",this),this.firstPlay=!0,this.stopTranslation();const t=!this.video.src&&!this.video.currentSrc&&!this.video.srcObject;this.votButton.container.hidden=t,t&&(this.votMenu.container.hidden=t),this.site.selector||(this.container=this.video.parentElement),this.container.contains(this.votButton.container)||this.container.append(this.votButton.container,this.votMenu.container),this.videoData=await this.getVideoData(),await this.updateSubtitles(),this.translateToLang=this.data.responseLanguage??"ru",this.setSelectMenuValues(this.videoData.detectedLanguage,this.videoData.responseLanguage)}async release(){N.log("[VideoHandler] release"),this.initialized=!1,this.releaseExtraEvents(),this.subtitlesWidget.release(),this.votButton.container.remove(),this.votMenu.container.remove()}}const ko=new class{constructor(){this.videoCache=new Set,this.onVideoAdded=new We,this.onVideoRemoved=new We,this.observer=new MutationObserver(this.handleMutations),this.intersectionObserver=new IntersectionObserver(this.handleIntersections,{threshold:.1})}handleMutations=t=>{window.requestIdleCallback((()=>{for(let e=0;e{for(let e=0;e{if(!t)return;const i=t.querySelectorAll("video");for(let t=0;t{this.videoCache.has(t)||(this.videoCache.add(t),this.intersectionObserver.observe(t))};handleIntersectingVideo=t=>{this.intersectionObserver.unobserve(t),(t=>{if(Ge.test(t.className)||Ge.test(t.title))return!0;let e=t.parentElement;for(;e;){if(Ge.test(e.className)||Ge.test(e.id))return!0;e=e.parentElement}return!1})(t)||(t=>t.hasAttribute("muted")&&!t.classList.contains("vjs-tech")&&!t.preload)(t)?N.log("The promotional/muted video was ignored",t):((t,e)=>{const o=()=>{(t=>t.readyState>=3)(t)?e(t):requestAnimationFrame(o)};o()})(t,this.handleVideoAdded)};handleVideoAdded=t=>{this.onVideoAdded.dispatch(t)};handleVideoRemoved=t=>{document.contains(t)||(this.videoCache.delete(t),this.onVideoRemoved.dispatch(t))}},To=new WeakMap;function Co(t,e){if(t.shadowRoot){let o=t.selector?Array.from(document.querySelectorAll(t.selector)).find((t=>t.shadowRoot.contains(e))):e.parentElement;return o&&o.shadowRoot?o.parentElement:o}const o=yo.browser.version?.split(".")?.[0];if(t.selector?.includes(":not")&&t.selector?.includes("*")&&o&&("Chrome"===yo.browser.name&&Number(o)<88||"Firefox"===yo.browser.name&&Number(o)<84)){const o=t.selector.split(" *")[0];return o?Array.from(document.querySelectorAll(o)).find((t=>t.contains(e))):e.parentElement}return t.selector?Array.from(document.querySelectorAll(t.selector)).find((t=>t.contains(e))):e.parentElement}(async function(){N.log("Loading extension..."),await J.update(),N.log(`Selected menu language: ${J.lang}`),"https://9animetv.to"===window.location.origin&&window.addEventListener("message",(t=>{if("https://rapid-cloud.co"===t.origin&&"getVideoId"===t.data){const t=/[^/]+$/.exec(window.location.href)?.[0],e=document.querySelector("#iframe-embed")?.contentWindow;e.postMessage(`getVideoId:${t}`,"https://rapid-cloud.co/")}})),ko.onVideoAdded.addListener((t=>{for(const e of function(){if(/(http(s)?:\/\/)(127\.0\.0\.1|localhost)/.exec(window.location.href))return[];const t=window.location.hostname,e=new URL(window.location),o=o=>o instanceof RegExp?o.test(t):"string"==typeof o?t.includes(o):"function"==typeof o&&o(e);return E.filter((t=>(Array.isArray(t.match)?t.match.some(o):o(t.match))&&t.host&&t.url))}()){if(!e)continue;let o=Co(e,t);if(o&&(("rumble"!==e.host||t.style.display)&&(["peertube","directlink"].includes(e.host)&&(e.url=window.location.origin),!To.has(t)))){To.set(t,new So(t,o,e));break}}})),ko.onVideoRemoved.addListener((async t=>{To.has(t)&&(await To.get(t).release(),To.delete(t))})),ko.enable()})().catch((t=>{console.error("[VOT]",t)}))})()})(); \ No newline at end of file + ${this.data?.subtitlesOpacity??20}`,this.data?.subtitlesOpacity??20,0,100),this.votSubtitlesDialog.bodyContainer.appendChild(this.votSubtitlesOpacitySlider.container),this.votSubtitlesHighlightWordsCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.highlightWords=Number(t.target.checked),await j.set("highlightWords",this.data.highlightWords),N.log("highlightWords value changed. New value: ",this.data.highlightWords),this.subtitlesWidget.setHighlightWords(this.data.highlightWords)})()})),this.votSubtitlesMaxLengthSlider.input.addEventListener("input",(t=>{(async()=>{this.data.subtitlesMaxLength=Number(t.target.value),await j.set("subtitlesMaxLength",this.data.subtitlesMaxLength),this.votSubtitlesMaxLengthSlider.label.querySelector("strong").textContent=`${this.data.subtitlesMaxLength}`,this.subtitlesWidget.setMaxLength(this.data.subtitlesMaxLength)})()})),this.votSubtitlesFontSizeSlider.input.addEventListener("input",(t=>{(async()=>{this.data.subtitlesFontSize=Number(t.target.value),await j.set("subtitlesFontSize",this.data.subtitlesFontSize),this.votSubtitlesFontSizeSlider.label.querySelector("strong").textContent=`${this.data.subtitlesFontSize}`,this.subtitlesWidget.setFontSize(this.data.subtitlesFontSize)})()})),this.votSubtitlesOpacitySlider.input.addEventListener("input",(t=>{(async()=>{this.data.subtitlesOpacity=Number(t.target.value),await j.set("subtitlesOpacity",this.data.subtitlesOpacity),this.votSubtitlesOpacitySlider.label.querySelector("strong").textContent=`${this.data.subtitlesOpacity}`,this.subtitlesWidget.setOpacity(this.data.subtitlesOpacity)})()})),document.documentElement.appendChild(this.votSubtitlesDialog.container)})),this.votShowPiPButtonCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.showPiPButton=Number(t.target.checked),await j.set("showPiPButton",this.data.showPiPButton),N.log("showPiPButton value changed. New value: ",this.data.showPiPButton),this.votButton.pipButton.hidden=!X()||!this.data.showPiPButton,this.votButton.separator2.hidden=!X()||!this.data.showPiPButton})()})),this.votM3u8ProxyHostTextfield.input.addEventListener("change",(t=>{(async()=>{this.data.m3u8ProxyHost=t.target.value||R,await j.set("m3u8ProxyHost",this.data.m3u8ProxyHost),N.log("m3u8ProxyHost value changed. New value: ",this.data.m3u8ProxyHost)})()})),this.votProxyWorkerHostTextfield.input.addEventListener("change",(t=>{(async()=>{this.data.proxyWorkerHost=t.target.value||$,await j.set("proxyWorkerHost",this.data.proxyWorkerHost),N.log("proxyWorkerHost value changed. New value: ",this.data.proxyWorkerHost),this.data.translateProxyEnabled&&(this.votClient.host=this.data.proxyWorkerHost)})()})),this.votAudioProxyCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.audioProxy=Number(t.target.checked),await j.set("audioProxy",this.data.audioProxy),N.log("audioProxy value changed. New value: ",this.data.audioProxy)})()})),this.votOnlyBypassMediaCSPCheckbox.input.addEventListener("change",(t=>{(async()=>{this.data.onlyBypassMediaCSP=Number(t.target.checked),await j.set("onlyBypassMediaCSP",this.data.onlyBypassMediaCSP),N.log("onlyBypassMediaCSP value changed. New value: ",this.data.onlyBypassMediaCSP),this.stopTranslate(),this.createPlayer()})()})),this.votNewAudioPlayerCheckbox.input.addEventListener("change",(t=>{(async()=>{const e=t.target.checked;this.data.newAudioPlayer=Number(e),await j.set("newAudioPlayer",this.data.newAudioPlayer),N.log("newAudioPlayer value changed. New value: ",this.data.newAudioPlayer),this.stopTranslate(),this.createPlayer(),this.votOnlyBypassMediaCSPCheckbox.input.disabled=this.votOnlyBypassMediaCSPCheckbox.container.hidden=!e})()})),this.votUpdateLocaleFilesButton.addEventListener("click",(()=>{(async()=>{await j.set("locale-hash",""),await J.update(!0),window.location.reload()})()})),this.votResetSettingsButton.addEventListener("click",(()=>{(async()=>{J.reset();const t=await j.list();for(let e=0;e{this.extraEvents.push({element:t,event:e,handler:o}),t.addEventListener(e,o)},e=(e,o,i)=>{for(const a of o)t(e,a,i)};if(this.resizeObserver=new ResizeObserver((t=>{for(let e=0;e550;this.votButton.container.dataset.position=this.votMenu.container.dataset.position=e?this.data?.buttonPos:"default",this.votButton.container.dataset.direction=this.data?.buttonPos&&"default"!==this.data?.buttonPos&&e?"column":"row"})),this.resizeObserver.observe(this.video),this.votMenu.container.setAttribute("style",`--vot-container-height: ${this.video.getBoundingClientRect().height}px`),["youtube","googledrive"].includes(this.site.host)&&"mobile"!==this.site.additionalData){this.syncVolumeObserver=new MutationObserver((t=>{if(this.audioPlayer.player.src&&this.data.syncVolume)for(let e=0;e{const e=t.target,o=this.votButton.container,i=this.votMenu.container,a=this.container,n=this.votSettingsDialog.container,r=document.querySelector(".vot-dialog-temp"),s=o.contains(e),l=i.contains(e),d=a.contains(e),u=n.contains(e),c=r?.contains(e)??!1;N.log(`[document click] ${s} ${l} ${d} ${u} ${c}`),s||l||u||c||(d||this.logout(0),this.votMenu.container.hidden=!0)})),document.addEventListener("keydown",(async t=>{const e=t.code,o=document.activeElement;["input","textarea"].includes(o.tagName.toLowerCase())||o.isContentEditable||e!==this.data.hotkeyButton||await this.handleTranslationBtnClick()}));let o=this.site.eventSelector?document.querySelector(this.site.eventSelector):this.container;o&&e(o,["mousemove","mouseout"],this.resetTimer),t(this.votButton.container,"mousemove",this.changeOpacityOnEvent),t(this.votMenu.container,"mousemove",this.changeOpacityOnEvent),e(document,["touchstart","touchmove","touchend"],this.changeOpacityOnEvent),t(this.votButton.container,"mousedown",(t=>{t.stopImmediatePropagation()})),t(this.votMenu.container,"mousedown",(t=>{t.stopImmediatePropagation()})),"youtube"===this.site.host&&(this.container.draggable=!1),"googledrive"===this.site.host&&(this.container.style.height="100%"),t(this.video,"canplay",(async()=>{"rutube"===this.site.host&&this.video.src||await this.setCanPlay()})),t(this.video,"emptied",(async()=>{this.video.src&&await pt(this.site,this.video)===this.videoData.videoId||(N.log("lipsync mode is emptied"),this.videoData="",this.stopTranslation())})),["rutube","ok"].includes(this.site.host)||t(this.video,"volumechange",(()=>{this.syncVideoVolumeSlider()})),"youtube"!==this.site.host||this.site.additionalData||t(document,"yt-page-data-updated",(async()=>{N.log("yt-page-data-updated"),window.location.pathname.includes("/shorts/")&&await this.setCanPlay()}))}async setCanPlay(){await pt(this.site,this.video)!==this.videoData.videoId&&(await this.handleSrcChanged(),await this.autoTranslate(),N.log("lipsync mode is canplay"))}logout(t){this.votMenu.container.hidden&&(this.votButton.container.style.opacity=t)}resetTimer=()=>{clearTimeout(this.timer),this.logout(1),this.timer=setTimeout((()=>{this.logout(0)}),1e3)};changeOpacityOnEvent=t=>{clearTimeout(this.timer),this.logout(1),t.stopPropagation()};async changeSubtitlesLang(t){if(N.log("[onchange] subtitles",t),this.votSubtitlesSelect.setSelected(t),"disabled"===t)this.votSubtitlesSelect.setTitle(J.get("VOTSubtitlesDisabled")),this.subtitlesWidget.setContent(null),this.votDownloadSubtitlesButton.hidden=!0,this.yandexSubtitles=null;else{const e=this.subtitlesList.at(parseInt(t));if(1===this.data.audioProxy&&e.url.startsWith("https://brosubs.s3-private.mds.yandex.net/vtrans/")){const t=e.url.replace("https://brosubs.s3-private.mds.yandex.net/vtrans/","");e.url=`https://${this.data.proxyWorkerHost}/video-subtitles/subtitles-proxy/${t}`,console.log(`[VOT] Subs proxied via ${e.url}`)}this.yandexSubtitles=await Me(e),this.subtitlesWidget.setContent(this.yandexSubtitles),this.votDownloadSubtitlesButton.hidden=!1}}async updateSubtitlesLangSelect(){const t=[{label:J.get("VOTSubtitlesDisabled"),value:"disabled",selected:!0,disabled:!1},...this.subtitlesList.map(((t,e)=>({label:(J.get("langs")[t.language]??t.language.toUpperCase())+(t.translatedFromLanguage?` ${J.get("VOTTranslatedFrom")} ${J.get("langs")[t.translatedFromLanguage]??t.translatedFromLanguage.toUpperCase()}`:"")+("yandex"!==t.source?`, ${window.location.hostname}`:"")+(t.isAutoGenerated?` (${J.get("VOTAutogenerated")})`:""),value:e,selected:!1,disabled:!1})))];this.votSubtitlesSelect.updateItems(t),await this.changeSubtitlesLang(t[0].value)}async updateSubtitles(){if(await this.changeSubtitlesLang("disabled"),!this.videoData.videoId)return console.error(`[VOT] ${J.getDefault("VOTNoVideoIDFound")}`),this.subtitlesList=[],this.subtitlesListVideoId=null,this.votButton.container.hidden=!0,void await this.updateSubtitlesLangSelect();if(this.votButton.container.hidden=!1,this.subtitlesListVideoId!==this.videoData.videoId){try{this.subtitlesList=await Ee(this.votClient,this.videoData)}catch(t){N.log("Error with yandex server, try auto-fix...",t),this.votOpts={fetchFn:it,hostVOT:D,host:this.data.proxyWorkerHost},this.votClient=new yt(this.votOpts),this.subtitlesList=await Ee(this.votClient,this.videoData),await j.set("translateProxyEnabled",1)}this.subtitlesList?this.subtitlesListVideoId=this.videoData.videoId:await this.changeSubtitlesLang("disabled"),await this.updateSubtitlesLangSelect()}}getVideoVolume(){let t=this.video?.volume;return["youtube","googledrive"].includes(this.site.host)&&(t=_e.getVideoVolume()??t),t}setVideoVolume(t){if(["youtube","googledrive"].includes(this.site.host)){if(_e.setVideoVolume(t))return this}return this.video.volume=t,this}isMuted(){return["youtube","googledrive"].includes(this.site.host)?_e.isMuted():this.video?.muted}syncVideoVolumeSlider(){const t=this.isMuted()?0:100*this.getVideoVolume(),e=Math.round(t);this.votVideoVolumeSlider.input.value=e,this.votVideoVolumeSlider.label.querySelector("strong").textContent=`${e}%`,ze.updateSlider(this.votVideoVolumeSlider.input),1===this.data.syncVolume&&(this.tempOriginalVolume=Number(e))}setSelectMenuValues(t,e){this.votTranslationLanguageSelect.fromSelect.setTitle(J.get("langs")[t]),this.votTranslationLanguageSelect.toSelect.setTitle(J.get("langs")[e]),this.votTranslationLanguageSelect.fromSelect.setSelected(t),this.votTranslationLanguageSelect.toSelect.setSelected(e),console.log(`[VOT] Set translation from ${t} to ${e}`),this.videoData.detectedLanguage=t,this.videoData.responseLanguage=e}syncVolumeWrapper(t,e){const o="translation"===t?this.votVideoVolumeSlider:this.votVideoTranslationVolumeSlider,i=Number(o.input.value),a=function(t,e,o,i){let a=e;return e>i?(a=o+(e-i),a=a>100?100:Math.max(a,0),t.volume=a/100):e100?100:Math.max(a,0),t.volume=a/100),a}("translation"===t?this.video:this.audioPlayer.player,e,i,"translation"===t?this.tempVolume:this.tempOriginalVolume);o.input.value=a,o.label.querySelector("strong").textContent=`${a}%`,ze.updateSlider(o.input),this.tempOriginalVolume="translation"===t?a:e,this.tempVolume="translation"===t?e:a}async getVideoData(){const{duration:t,url:e,videoId:o,host:i,title:a,translationHelp:n,detectedLanguage:r,subtitles:s}=await gt(this.site,this.video),l={translationHelp:n??null,isStream:!1,duration:this.video?.duration||t||P.defaultDuration,videoId:o,url:e,host:i,detectedLanguage:r??this.translateFromLang,responseLanguage:this.translateToLang,subtitles:s,title:a};if("youtube"===this.site.host){const t=await _e.getVideoData();l.isStream=t.isLive,t.title&&(l.detectedLanguage=t.detectedLanguage,l.title=t.localizedTitle)}else if(["rutube","ok.ru","mail_ru"].includes(this.site.host))l.detectedLanguage="ru";else if("youku"===this.site.host)l.detectedLanguage="zh";else if("vk"===this.site.host){const t=document.getElementsByTagName("track")?.[0]?.srclang;l.detectedLanguage=t||"auto"}else"weverse"===this.site.host?l.detectedLanguage="ko":["bilibili","bitchute","rumble","peertube","dailymotion","trovo","yandexdisk","coursehunterLike","archive","nineanimetv","directlink"].includes(this.site.host)&&(l.detectedLanguage="auto");return l}videoValidator(){if(["youtube","ok.ru","vk"].includes(this.site.host)&&(N.log("VideoValidator videoData: ",this.videoData),1===this.data.dontTranslateYourLang&&this.videoData.detectedLanguage===this.data.dontTranslateLanguage))throw new mt("VOTDisableFromYourLang");if(!this.videoData.isStream&&this.videoData.duration>14400)throw new mt("VOTVideoIsTooLong");return!0}stopTranslate(){this.audioPlayer.player.removeVideoEvents(),this.audioPlayer.player.clear(),this.audioPlayer.player.src=void 0,N.log("audioPlayer after stopTranslate",this.audioPlayer),this.votVideoVolumeSlider.container.hidden=!0,this.votVideoTranslationVolumeSlider.container.hidden=!0,this.votDownloadButton.hidden=!0,this.downloadTranslationUrl=null,this.transformBtn("none",J.get("translateVideo")),N.log(`Volume on start: ${this.volumeOnStart}`),this.volumeOnStart&&this.setVideoVolume(this.volumeOnStart),clearInterval(this.streamPing),clearTimeout(this.autoRetry),this.hls?.destroy(),this.hls=Q(),this.firstSyncVolume=!0}async translateExecutor(t){N.log("Run translateFunc",t),await this.translateFunc(t,this.videoData.isStream,this.videoData.detectedLanguage,this.videoData.responseLanguage,this.videoData.translationHelp)}async updateTranslationErrorMsg(t){const e=J.get("translationTake"),o=J.lang;if("VOTLocalizedError"===t?.name)this.transformBtn("error",t.localizedMessage);else if(t instanceof Error)this.transformBtn("error",t?.message);else if(1!==this.data.translateAPIErrors||t.includes(e)||"ru"===o)this.transformBtn("error",t);else{this.setLoadingBtn(!0);const e=await async function(t,e="",o="ru"){switch(await j.get("translationService",q)){case"yandex":{const i=e&&o?`${e}-${o}`:o;return await we.translate(t,i)}case"deepl":return await Se.translate(t,e,o);default:return t}}(t,"ru",o);this.transformBtn("error",e)}["Подготавливаем перевод","Видео передано в обработку","Ожидаем перевод видео","Загружаем переведенное аудио"].includes(t)&&this.setLoadingBtn(!0)}afterUpdateTranslation(t){this.votVideoVolumeSlider.container.hidden=1!==this.data.showVideoSlider||"success"!==this.votButton.container.dataset.status,this.votVideoTranslationVolumeSlider.container.hidden="success"!==this.votButton.container.dataset.status,1===this.data.autoSetVolumeYandexStyle&&(this.votVideoVolumeSlider.input.value=100*this.data.autoVolume,this.votVideoVolumeSlider.label.querySelector("strong").textContent=100*this.data.autoVolume+"%",ze.updateSlider(this.votVideoVolumeSlider.input)),this.votDownloadButton.hidden=!1,this.downloadTranslationUrl=t}async validateAudioUrl(t){try{const e=await it(t,{method:"HEAD",timeout:5e3});if(N.log("Test audio response",e),404!==e.status)return N.log("Valid audioUrl",t),t;N.log("Yandex returned not valid audio, trying to fix...");let o=await this.translateVideoImpl(this.videoData,this.videoData.detectedLanguage="auto",this.videoData.responseLanguage,this.videoData.translationHelp);this.setSelectMenuValues(this.videoData.detectedLanguage,this.videoData.responseLanguage),t=o.url,N.log("Fixed audio audioUrl",t)}catch(t){"Timeout"===t.message?(N.log("Request timed out. Handling timeout error..."),this.data.audioProxy=1,await j.set("audioProxy",1)):N.log("Test audio error:",t)}return t}async updateTranslation(t){if(this.cachedTranslation?.url!==this.audioPlayer.player.currentSrc&&(t=await this.validateAudioUrl(t)),1===this.data.audioProxy&&t.startsWith("https://vtrans.s3-private.mds.yandex.net/tts/prod/")){const e=t.replace("https://vtrans.s3-private.mds.yandex.net/tts/prod/","");t=`https://${this.data.proxyWorkerHost}/video-translation/audio-proxy/${e}`,console.log(`[VOT] Audio proxied via ${t}`)}this.audioPlayer.player.src!==t&&(this.audioPlayer.player.src=t);try{this.audioPlayer.init()}catch(t){t.message.includes("Failed to fetch audio file")?(this.videoHandler.data.audioProxy=1,await j.set("audioProxy",1)):this.videoHandler.transformBtn("error",t.message)}this.setupAudioSettings(),"twitter"===this.site.host&&document.querySelector('button[data-testid="app-bar-back"][role="button"]').addEventListener("click",this.stopTranslation),this.transformBtn("success",J.get("disableTranslate")),this.afterUpdateTranslation(t)}async translateFunc(t,e,o,i,a){if(console.log("[VOT] Video Data: ",this.videoData),N.log("Run videoValidator"),this.videoValidator(),this.setLoadingBtn(!0),this.volumeOnStart=this.getVideoVolume(),e){let t=await this.translateStreamImpl(this.videoData,o,i);if(!t)return void N.log("Skip translation");this.transformBtn("success",J.get("disableTranslate"));const e=this.setHLSSource(t.result.url);return"youtube"===this.site.host&&_e.videoSeek(this.video,10),this.setupAudioSettings(),this.video.src||this.video.currentSrc||this.video.srcObject?this.afterUpdateTranslation(e):this.stopTranslation()}if(this.cachedTranslation=this.videoTranslations.find((e=>e.videoId===t&&e.expires>at()&&e.from===o&&e.to===i)),this.cachedTranslation)return await this.updateTranslation(this.cachedTranslation.url),void N.log("[translateFunc] Cached translation was received");let n=await this.translateVideoImpl(this.videoData,o,i,a);N.log("[translateRes]",n),n?(await this.updateTranslation(n.url),this.subtitlesList.some((t=>"yandex"===t.source&&t.translatedFromLanguage===this.videoData.detectedLanguage&&t.language===this.videoData.responseLanguage))||(this.subtitlesList=await Ee(this.votClient,this.videoData),await this.updateSubtitlesLangSelect()),this.videoTranslations.push({videoId:t,from:o,to:i,url:this.downloadTranslationUrl,expires:at()+this.videoTranslationTTL})):N.log("Skip translation")}setupHLS(t){this.hls.on(Hls.Events.MEDIA_ATTACHED,(function(){N.log("audio and hls.js are now bound together !")})),this.hls.on(Hls.Events.MANIFEST_PARSED,(function(t){N.log("manifest loaded, found "+t?.levels?.length+" quality level")})),this.hls.loadSource(t),this.hls.attachMedia(this.audioPlayer.player.audio),this.hls.on(Hls.Events.ERROR,(function(t){if(t.fatal)switch(t.type){case Hls.ErrorTypes.MEDIA_ERROR:console.log("fatal media error encountered, try to recover"),this.hls.recoverMediaError();break;case Hls.ErrorTypes.NETWORK_ERROR:console.error("fatal network error encountered",t);break;default:this.hls.destroy()}})),N.log(this.hls)}setHLSSource(t){const e=`https://${this.data.m3u8ProxyHost}/?all=yes&origin=${encodeURIComponent("https://strm.yandex.ru")}&referer=${encodeURIComponent("https://strm.yandex.ru")}&url=${encodeURIComponent(t)}`;if(this.hls)this.setupHLS(e);else{if(!this.audioPlayer.player.audio.canPlayType("application/vnd.apple.mpegurl"))throw new mt("audioFormatNotSupported");this.audioPlayer.player.src=e}return e}setupAudioSettings(){"number"==typeof this.data.defaultVolume&&(this.audioPlayer.player.volume=this.data.defaultVolume/100),"number"==typeof this.data.autoSetVolumeYandexStyle&&this.data.autoSetVolumeYandexStyle&&this.setVideoVolume(this.data.autoVolume)}stopTranslation=()=>{this.stopTranslate(),this.syncVideoVolumeSlider()};async handleSrcChanged(){N.log("[VideoHandler] src changed",this),this.firstPlay=!0,this.stopTranslation();const t=!this.video.src&&!this.video.currentSrc&&!this.video.srcObject;this.votButton.container.hidden=t,t&&(this.votMenu.container.hidden=t),this.site.selector||(this.container=this.video.parentElement),this.container.contains(this.votButton.container)||this.container.append(this.votButton.container,this.votMenu.container),this.videoData=await this.getVideoData(),await this.updateSubtitles(),this.translateToLang=this.data.responseLanguage??"ru",this.setSelectMenuValues(this.videoData.detectedLanguage,this.videoData.responseLanguage)}async release(){N.log("[VideoHandler] release"),this.initialized=!1,this.releaseExtraEvents(),this.subtitlesWidget.release(),this.votButton.container.remove(),this.votMenu.container.remove()}}const ko=new class{constructor(){this.videoCache=new Set,this.onVideoAdded=new We,this.onVideoRemoved=new We,this.observer=new MutationObserver(this.handleMutations),this.intersectionObserver=new IntersectionObserver(this.handleIntersections,{threshold:.1})}handleMutations=t=>{window.requestIdleCallback((()=>{for(let e=0;e{for(let e=0;e{if(!t)return;const i=t.querySelectorAll("video");for(let t=0;t{this.videoCache.has(t)||(this.videoCache.add(t),this.intersectionObserver.observe(t))};handleIntersectingVideo=t=>{this.intersectionObserver.unobserve(t),(t=>{if(Ge.test(t.className)||Ge.test(t.title))return!0;let e=t.parentElement;for(;e;){if(Ge.test(e.className)||Ge.test(e.id))return!0;e=e.parentElement}return!1})(t)||(t=>t.hasAttribute("muted")&&!t.classList.contains("vjs-tech")&&!t.preload)(t)?N.log("The promotional/muted video was ignored",t):((t,e)=>{const o=()=>{(t=>t.readyState>=3)(t)?e(t):requestAnimationFrame(o)};o()})(t,this.handleVideoAdded)};handleVideoAdded=t=>{this.onVideoAdded.dispatch(t)};handleVideoRemoved=t=>{document.contains(t)||(this.videoCache.delete(t),this.onVideoRemoved.dispatch(t))}},To=new WeakMap;function Co(t,e){if(t.shadowRoot){let o=t.selector?Array.from(document.querySelectorAll(t.selector)).find((t=>t.shadowRoot.contains(e))):e.parentElement;return o&&o.shadowRoot?o.parentElement:o}const o=yo.browser.version?.split(".")?.[0];if(t.selector?.includes(":not")&&t.selector?.includes("*")&&o&&("Chrome"===yo.browser.name&&Number(o)<88||"Firefox"===yo.browser.name&&Number(o)<84)){const o=t.selector.split(" *")[0];return o?Array.from(document.querySelectorAll(o)).find((t=>t.contains(e))):e.parentElement}return t.selector?Array.from(document.querySelectorAll(t.selector)).find((t=>t.contains(e))):e.parentElement}(async function(){N.log("Loading extension..."),await J.update(),N.log(`Selected menu language: ${J.lang}`),"https://9animetv.to"===window.location.origin&&window.addEventListener("message",(t=>{if("https://rapid-cloud.co"===t.origin&&"getVideoId"===t.data){const t=/[^/]+$/.exec(window.location.href)?.[0],e=document.querySelector("#iframe-embed")?.contentWindow;e.postMessage(`getVideoId:${t}`,"https://rapid-cloud.co/")}})),ko.onVideoAdded.addListener((t=>{for(const e of function(){if(/(http(s)?:\/\/)(127\.0\.0\.1|localhost)/.exec(window.location.href))return[];const t=window.location.hostname,e=new URL(window.location),o=o=>o instanceof RegExp?o.test(t):"string"==typeof o?t.includes(o):"function"==typeof o&&o(e);return E.filter((t=>(Array.isArray(t.match)?t.match.some(o):o(t.match))&&t.host&&t.url))}()){if(!e)continue;let o=Co(e,t);if(o&&(("rumble"!==e.host||t.style.display)&&(["peertube","directlink"].includes(e.host)&&(e.url=window.location.origin),!To.has(t)))){To.set(t,new So(t,o,e));break}}})),ko.onVideoRemoved.addListener((async t=>{To.has(t)&&(await To.get(t).release(),To.delete(t))})),ko.enable()})().catch((t=>{console.error("[VOT]",t)}))})()})(); \ No newline at end of file diff --git a/dist/vot.user.js b/dist/vot.user.js index 386090fb..5865eaa8 100644 --- a/dist/vot.user.js +++ b/dist/vot.user.js @@ -165,7 +165,7 @@ // @connect onrender.com // @connect workers.dev // @namespace vot -// @version 1.7.1-beta3 +// @version 1.7.1-beta4 // @icon https://translate.yandex.ru/icons/favicon.ico // @author sodapng, mynovelhost, Toil, SashaXser, MrSoczekXD // @homepageURL https://github.com/ilyhalight/voice-over-translation @@ -7498,7 +7498,7 @@ class VideoObserver { ;// ./node_modules/chaimu/dist/config.js /* harmony default export */ const dist_config = ({ - version: "1.0.1", + version: "1.0.2", debug: false, fetchFn: fetch.bind(window), }); @@ -8486,10 +8486,15 @@ class AudioPlayer extends BasePlayer { }); } set src(url) { + this._src = url; + if (!url) { + void this.clear(); + return; + } this.audio.src = url; } get src() { - return this.audio.src; + return this._src; } get currentSrc() { return this.audio.currentSrc; @@ -8592,7 +8597,8 @@ class ChaimuPlayer extends BasePlayer { try { await this.chaimu.audioContext.close(); } - catch { } + catch { + } return this; } async clear() { @@ -8816,10 +8822,13 @@ class VideoHandler { * @type {import("./index").VideoHandler['audioContext']} */ audioContext = initAudioContext(); - // audioPlayer = new AudioPlayer(this); hls = initHls(); // debug enabled only in dev mode votClient; + + /** + * @type {import("chaimu").default} + */ audioPlayer; videoTranslations = []; @@ -9761,13 +9770,16 @@ class VideoHandler { this.audioPlayer.player, ); if (this.audioPlayer.player.src) { - debug.log("[click translationBtn] audio.src is not empty"); + debug.log( + "[click translationBtn] audio.src is not empty", + this.audioPlayer.player.src, + ); this.stopTranslate(); return; } if (this.hls.url) { - debug.log("[click translationBtn] hls is not empty"); + debug.log("[click translationBtn] hls is not empty", this.hls.url); this.stopTranslate(); return; } @@ -10919,6 +10931,7 @@ class VideoHandler { this.audioPlayer.player.removeVideoEvents(); this.audioPlayer.player.clear(); this.audioPlayer.player.src = undefined; + debug.log("audioPlayer after stopTranslate", this.audioPlayer); this.votVideoVolumeSlider.container.hidden = true; this.votVideoTranslationVolumeSlider.container.hidden = true; diff --git a/package.json b/package.json index 2379e0d6..e22c06dc 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ }, "dependencies": { "bowser": "^2.11.0", - "chaimu": "^1.0.1", + "chaimu": "^1.0.2", "lit": "^3.2.1", "requestidlecallback-polyfill": "^1.0.2", "vot.js": "^1.3.6" diff --git a/src/headers.json b/src/headers.json index adda73de..b4fb44c7 100644 --- a/src/headers.json +++ b/src/headers.json @@ -1,7 +1,7 @@ { "name": "[VOT] - Voice Over Translation", "description": "A small extension that adds a Yandex Browser video translation to other browsers", - "version": "1.7.1-beta3", + "version": "1.7.1-beta4", "author": "sodapng, mynovelhost, Toil, SashaXser, MrSoczekXD", "namespace": "vot", "icon": "https://translate.yandex.ru/icons/favicon.ico", diff --git a/src/index.js b/src/index.js index 343c91be..1c069845 100644 --- a/src/index.js +++ b/src/index.js @@ -100,10 +100,13 @@ class VideoHandler { * @type {import("./index").VideoHandler['audioContext']} */ audioContext = initAudioContext(); - // audioPlayer = new AudioPlayer(this); hls = initHls(); // debug enabled only in dev mode votClient; + + /** + * @type {import("chaimu").default} + */ audioPlayer; videoTranslations = []; @@ -1045,13 +1048,16 @@ class VideoHandler { this.audioPlayer.player, ); if (this.audioPlayer.player.src) { - debug.log("[click translationBtn] audio.src is not empty"); + debug.log( + "[click translationBtn] audio.src is not empty", + this.audioPlayer.player.src, + ); this.stopTranslate(); return; } if (this.hls.url) { - debug.log("[click translationBtn] hls is not empty"); + debug.log("[click translationBtn] hls is not empty", this.hls.url); this.stopTranslate(); return; } @@ -2201,6 +2207,7 @@ class VideoHandler { this.audioPlayer.player.removeVideoEvents(); this.audioPlayer.player.clear(); this.audioPlayer.player.src = undefined; + debug.log("audioPlayer after stopTranslate", this.audioPlayer); this.votVideoVolumeSlider.container.hidden = true; this.votVideoTranslationVolumeSlider.container.hidden = true;