@vkontakte/videoplayer-statistics 1.0.83 → 1.0.84-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/evergreen.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @vkontakte/videoplayer-statistics v1.0.83
3
- * Tue, 05 Aug 2025 13:54:03 GMT
4
- * https://st.mycdn.me/static/vkontakte-videoplayer/1-0-83/doc/
2
+ * @vkontakte/videoplayer-statistics v1.0.84-beta.0
3
+ * Thu, 14 Aug 2025 12:56:02 GMT
4
+ * https://st.mycdn.me/static/vkontakte-videoplayer/1-0-84/doc/
5
5
  */
6
- var Tt=Object.defineProperty;var xt=(s,e)=>{for(var i in e)Tt(s,i,{get:e[i],enumerable:!0})};var R=(a=>(a.PROD="prod",a.VK_ALIAS="vk_alias",a.VIDEOTEST="videotest",a.TEST="test",a.OKCDN="okcdn",a.AUTO="auto",a))(R||{}),re=(c=>(c.Q144P="mobile",c.Q240P="lowest",c.Q360P="low",c.Q480P="medium",c.Q720P="high",c.Q1080P="fullhd",c.Q1440P="quadhd",c.Q2160P="ultrahd",c.UNKNOWN="unknown",c))(re||{}),se=(u=>(u.MP4="mp4",u.DASH="dash",u.DASH_SEP="dash_sep",u.ONDEMAND_DASH="ondemand_dash",u.HLS="hls",u.ONDEMAND_HLS="ondemand_hls",u.WEBM="webm",u.AV1="av1",u.ONDEMAND_DASH_LIVE="ondemand_dash_live",u.ONDEMAND_HLS_LIVE="ondemand_hls_live",u.WEBRTC="webrtc",u.UNKNOWN="unknown",u.RTMP="rtmp",u))(se||{});var ae=(t=>(t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3",t))(ae||{});var ne=(n=>(n.SLIDER="slider",n.DOUBLE_TAP="double_tap",n.TIME_CODE="time_code",n.EPISODE="episode",n.REWIND="rewind",n.LIVE="live",n.UNKNOWN="unknown",n))(ne||{}),xe=(r=>(r.GRAPH_SHOW="iGraphShow",r.GRAPH_HIDE="iGraphHide",r.NEXT_AREA="iNextChapterArea",r.NEXT_BUTTON="iNextChapterBtn",r.WATCH_AGAIN="iWatchAgainBtn",r))(xe||{}),ke={action_play:"ap",action_play_interactive:"api",first_bytes:"fb",player_ready:"pr",first_frame:"ff",seek:"sk",watch_coverage_record:"wr",watch_coverage_live:"wl",empty_buffer:"eb",action_stop:"as",close_at_empty_buffer:"cb",content_error:"er",player_interface_click:"pc",next_movie:"nm",track_switch:"ts",failover:"fo",quality:"qt"},Le={vsid:"si",isid:"is",vid:"vi",place:"pl",quality:"qt",cdn_host:"ch",stat_type:"st",param:"pm",vk_app_id:"va",track_code:"tc",connection_type:"cnt",connection_reused:"cr",cached_data:"cd",live:"lv",muted:"mu",mode:"mo",subtitles:"sb",failover:"fo",download_speed:"ds",manual_quality:"mq",ref_domain:"rd",direct_url:"du"},Ce={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},$e={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv"};import{fillWithDefault as kt}from"@vkontakte/videoplayer-shared/evergreen";var De="CIOPGQJGDIHBABABA",de={prod:"https://api.ok.ru",vk_alias:"https://api.mycdn.me",videotest:"https://videotestapi.ok.ru/api",test:"https://apitest.ok.ru",okcdn:"https://api.okcdn.ru",auto:""};var Lt={apiEnv:"vk_alias",apiKey:De,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageInterval:15e3,disabledOperations:["quality"],disabledCustomFields:[],shorten:!0,maxLoops:100,embedUrlParams:[],useBeacon:!0,synchronizeTime:!0,debugLog:!1,clearStorageAtUnload:!0,useVKComIsMobileLogic:!1,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1},useKeepalive:!1},Ne=s=>kt(s,Lt);function ce(){let s="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36),i=0,t,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),t=i&15,i=i>>4,e[o]=s[o===19?t&3|8:t]);return e.join("")}import{assertNonNullable as Wt,combine as Qe,fromEvent as je,isNonNullable as D,isNullable as Ge,merge as Kt,now as x,observableFrom as qt,once as zt,safeStorage as Ye,Subject as Qt,Subscription as be,ValueSubject as z,createURL as Xe}from"@vkontakte/videoplayer-shared/evergreen";import{Logger as jt,detectEmbed as Gt}from"@vkontakte/videoplayer-shared/evergreen";var Oe=s=>{let{operation:e,custom:i}=s,t=Object.fromEntries(Object.entries(i).map(([o,r])=>{let a=Le[o]??o,n=r;return r&&(o==="mode"?n=$e[r]??r:o==="quality"&&(n=Ce[r]??r)),[a,n]}));return{...s,operation:ke[e]??e,custom:t}};var P="1.0.83";import{ValueSubject as Ct,getExponentialDelay as $t,ErrorCategory as C}from"@vkontakte/videoplayer-shared/evergreen";var Dt=/Mobile|mini|Fennec|Android|iP(ad|od|hone)|opera (mini|mobi)/i,V=class{constructor(e){this.consequentAuthErrors=0;this.authorized$=new Ct(!1);this.params=e}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(e){let i="log.externalLog",t=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,t,o)||this.logRequest(e).catch(()=>{})}async logRequest(e){let i="log.externalLog",t=this.createLogParams(e),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;let r=async(a,n=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,o)}catch(l){if(!l||!("error_code"in l)){this.params.error$.next({id:"logRequestUnknown",category:C.NETWORK,message:`Unknown ${i} error`,thrown:l});return}let c=l?.error_code;switch(c){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),n>0?r(a,n-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),n>0?r(a,n-1):void 0;default:{this.params.error$.next({id:`LogRequest#${c}`,category:C.EXTERNAL_API,message:`${i} error`,data:l});return}}}};return r(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){let i="WEB",t=!1,o=`@vkontakte/videoplayer-statistics:${P}`;if(this.params.config.useVKComIsMobileLogic){let{appVersion:r}=window.navigator;t=Dt.test(r)}else this.params.mobile&&(t=!0);return t&&(i="M_WEB"),this.params.vktvVersion&&(i="SMART_TV",o=this.params.vktvVersion),{collector:"ok.mobile.apps.video",data:JSON.stringify({application:o,platform:i,items:this.params.config.shorten?e.map(Oe):e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();let e=$t(this.consequentAuthErrors,this.params.config.backoff);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(t=>this.params.error$.next({id:"AuthorizeBackoff",category:C.NETWORK,message:"Otherwise unhandled error in authorization",thrown:t})).finally(()=>this.backoffTimeoutId=0)},e))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);let e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.deviceId,client_version:P.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(i.session_data.auth_token=this.authToken,i.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,i).then(t=>((!t||!t.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:C.EXTERNAL_API,message:"No session key",data:t}),this.sessionKey=t?.session_key??void 0,this.sessionKey)).catch(async t=>{this.sessionKey=void 0;let o=t?.error_code;switch(o){case 401:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:C.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:C.NETWORK,message:"authorize error",thrown:t})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}};import{ErrorCategory as B,now as ue}from"@vkontakte/videoplayer-shared/evergreen";var M=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=de[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!=="auto"||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{let e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(e){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:B.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),de.vk_alias}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(e,i,t){if(!window.Blob||!window.navigator.sendBeacon)return!1;let o=this._prepareQueryParams({method:e,queryParams:i,sessionKey:t}),r=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,r)}catch(a){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:B.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t){let o=ue(),r=n=>{if(n instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(n.message)){this.params.error$.next({id:"Network",category:B.NETWORK,message:"Request failed",thrown:n});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:B.NETWORK,message:"Unhandled request error",thrown:n,data:{method:e,params:i,sessionKey:t,time:ue()-o}})};this.apiBaseUrl=await this.resolveApiBaseUrl();let a={method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:i,sessionKey:t})};return this.params.config.useKeepalive&&(a.keepalive=!0),fetch(`${this.apiBaseUrl}/fb.do`,a).then(n=>{let l=Number(n.headers.get("content-length"))===0,c=new Date(n.headers.get("date")??"").getTime(),h=ue()-o;if(isFinite(c)&&this.timeSynchronisation?.addServerTime(c,h),!l)return n.json().then(p=>Object.prototype.hasOwnProperty.call(p,"error_msg")?Promise.reject(p):p,r)},r)}_prepareQueryParams(e){let i=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&i.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([t,o])=>i.append(t,typeof o=="string"?o:JSON.stringify(o))),i}};import{ErrorCategory as Nt,now as Ot,safeStorage as U,debounceFn as Re}from"@vkontakte/videoplayer-shared/evergreen";var H="onestat_events",le=s=>e=>e.timestamp+s>=Ot(),W=class{constructor(e){this.unsaltedStorage=[];this.isPaused=!1;this.isUrgent=e=>{let{operation:i}=e;return["action_play","watch_coverage_record","watch_coverage_live"].includes(i)};this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=Re(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=U.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=Re(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(t=>{t&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:Nt.WTF,message:e?String(e):"Unknown logger error",thrown:e})}}readFromStorage(){let e=U.get(H);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}let i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(le(this.params.config.storageExpiration));U.set(H,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(le(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],U.set(H,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(le(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${t.length} retrieved from storage, ${o.length} of them actual`})}U.set(H,JSON.stringify(e))}log(e){this.addToStorage(e),!this.isPaused&&(this.isUrgent(e)?this.flush():this.lastVsid!==e.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=e.custom.vsid)}flush({wantBeacon:e,clearStorage:i}={wantBeacon:!1,clearStorage:!0}){let t=this.getFromStorage();t.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${t.length} events through beacon`}),this.api.logBeacon(t)):(this.loggerDebugLog({message:`Flushing ${t.length} events`}),this.api.logRequest(t)),i&&this.markStorageSent()):this.api.authorize(),this.firstFlush.cancel(),this.debouncedFlush.cancel())}pause(){this.isPaused=!0,this.debouncedFlush.cancel()}resume(){this.isPaused=!1,this.debouncedFlush()}destroy(){this.subscription.unsubscribe(),this.firstFlush.cancel(),this.debouncedFlush.cancel()}};import{HttpConnectionType as he,Surface as $,VideoFormat as v,VideoQuality as _}from"@vkontakte/videoplayer-core/evergreen";import{assertNever as Ve}from"@vkontakte/videoplayer-shared/evergreen";var Me=s=>s&&{[_.INVARIANT]:"unknown",[_.Q_144P]:"mobile",[_.Q_240P]:"lowest",[_.Q_360P]:"low",[_.Q_480P]:"medium",[_.Q_576P]:"unknown",[_.Q_720P]:"high",[_.Q_1080P]:"fullhd",[_.Q_1440P]:"quadhd",[_.Q_2160P]:"ultrahd",[_.Q_4320P]:"unknown"}[s],pe=s=>s&&{[he.HTTP1]:"http1",[he.HTTP2]:"http2",[he.QUIC]:"http3"}[s],Ue=s=>{if(s!==void 0)switch(s){case v.MPEG:return"mp4";case v.DASH:case v.DASH_LIVE:case v.DASH_STREAMS:return"dash";case v.DASH_SEP:return"dash_sep";case v.DASH_ONDEMAND:return"ondemand_dash";case v.DASH_WEBM:case v.DASH_LIVE_WEBM:return"webm";case v.DASH_WEBM_AV1:return"av1";case v.DASH_LIVE_CMAF:return"ondemand_dash_live";case v.HLS:case v.HLS_LIVE:return"hls";case v.HLS_ONDEMAND:return"ondemand_hls";case v.HLS_LIVE_CMAF:return"ondemand_hls_live";case v.WEB_RTC_LIVE:return"webrtc";default:return Ve(s)}},K=s=>{if(s!==void 0)switch(s){case $.NONE:case $.INLINE:return;case $.FULLSCREEN:return"fullscreen";case $.SECOND_SCREEN:return"chromecast";case $.PIP:return"pip";case $.INVISIBLE:return"invisible";default:return Ve(s)}},Fe=s=>{switch(s){case"slow-2g":return"poor";case"2g":return"poor";case"3g":return"good";case"4g":return"excellent"}};var q=class{constructor(e){this.offset=void 0;this.offset=e}getOffset(){return this.offset??0}setOffset(e){this.offset=e}now(){return Date.now()+(this.offset??0)}date(e=new Date){return e.setTime(e.getTime()+(this.offset??0)),e}addServerTime(e,i){let t=Date.now(),o=e-t-i/2;if(Math.abs(o)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(o):this.offset=Math.round(.2*o+(1-.2)*this.offset)}};var Be=()=>Math.floor(Math.random()*4294967296).toString(36).padStart(7,"0"),He=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");import{PlaybackState as We}from"@vkontakte/videoplayer-core/evergreen";import{filter as Ke,filterChanged as Vt,fromEvent as Mt,isNullable as qe,map as Ut,merge as fe,Observable as Ft,Subject as ge,Subscription as Bt,ValueSubject as Ht}from"@vkontakte/videoplayer-shared/evergreen";var ze=(s,e)=>new Ft(i=>{let t=new Bt,o=fe(Mt(window,"beforeunload"),s.events.willDestruct$),r=new Ht(void 0),a;t.add(s.info.isLive$.pipe(Vt()).subscribe(g=>{a&&(a.unsubscribe(),r.next(void 0)),g?a=s.info.liveTime$.pipe(Ut(y=>y&&y/1e3)).subscribe(r):a=s.info.position$.subscribe(r),t.add(a)}));let{playing$:n,paused$:l}=s.events,c=s.events.willSeek$.pipe(Ke(()=>s.info.playbackState$.getValue()===We.PLAYING)),h=s.events.seeked$.pipe(Ke(()=>s.info.playbackState$.getValue()===We.PLAYING)),p=!1,d=new ge;t.add(c.subscribe(()=>{p||d.next(),p=!0})),t.add(h.subscribe(()=>p=!1));let u=new ge,m=new ge,f=fe(n,h,u),I=fe(l,d,o,s.events.looped$,m),S,A=()=>S=r.getValue(),w=()=>{let g=r.getValue();qe(S)||S===g||qe(g)||(i.next({from:S,to:g}),S=void 0)},T=()=>{m.next(),u.next()};if(t.add(f.subscribe(A)),t.add(I.subscribe(w)),e.forceInterval&&isFinite(e.forceInterval)){let g=0;t.add(f.subscribe(()=>g=window.setTimeout(T,e.forceInterval))),t.add(I.subscribe(()=>window.clearTimeout(g)))}return t});var Yt="_one-stat_",Je=`${Yt}deviceId`,me=()=>{let s=new be;return{subscription:s,subscribe:(e,i)=>{e&&s.add(e.subscribe(i))}}},ve=class{constructor(e,i){this.subscription=new be;this.debugLogger=new jt;this.oneStatDebugLog=this.debugLogger.createComponentLog("onestat");this.loopCounter=0;this.disabled=!1;this.vsid$=new z(void 0);this.isid$=new z(void 0);this.zenUid$=new z(void 0);this.seekAction$=new z("unknown");this.statContext=e,this.config=Ne(i.config??{}),D(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new q);let t=new Qt;this.experimental={error$:t};let o=Ye.get(Je);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=ce(),Ye.set(Je,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??He()),this.zenUid$.next(i.zenUid);let r=new M({config:this.config,error$:t,timeSynchronisation:this.timeSynchronisation});this.api=new V({config:this.config,apiTransport:r,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,deviceId:this.deviceId,error$:t,vktvVersion:i.vktvVersion}),this.logger=new W({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:a,topOrigin:n}=Gt();this.isEmbed=a,this.embedParent=n?new URL(n).hostname:void 0,this.subscribe()}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){let i=new be,t=(d,u)=>i.add(d.subscribe(u));t(e.events.willStart$,()=>{let d=e.info.position$.getValue();this.logActionPlay({position:d}),this.statContext.projectId&&this.logActionPlayInteractive()}),t(e.events.looped$,()=>{this.resetViewSession(),++this.loopCounter>this.config.maxLoops&&(this.disabled=!0),this.logActionPlay({position:e.info.position$.getValue()})}),t(e.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:e.info.position$.getValue()}),this.seekAction$.next("unknown")}),t(e.events.paused$,()=>{this.logPause({position:e.info.position$.getValue()})}),t(e.events.willResume$,()=>{this.logPlay()}),t(e.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),t(e.events.playing$,()=>{this.logPlaying()}),t(ze(e,{forceInterval:this.config.watchCoverageInterval}),d=>{let u=e.info.isLive$.getValue(),m=e.info.atLiveEdge$.getValue(),f={start:parseFloat(d.from.toFixed(3)),end:parseFloat(d.to.toFixed(3))};if(m){let I=e.info.liveLatency$.getValue()??0,S=e.info.currentBuffer$.getValue()?.end??0,A=e.info.liveBufferTime$.getValue()??0,w=Math.round((I-(S-A))*1e3),T=Math.round(I*1e3);w&&T&&(f.latency=w,f.bufferLatency=T)}u?this.logWatchCoverageLive(f):this.logWatchCoverageRecord(f)});let o;t(e.info.isStalled$,d=>{d?o=x():(D(o)&&this.logEmptyBuffer({duration:x()-o}),o=void 0)});let r=!1;i.add(e.events.fatalError$.pipe(zt()).subscribe(()=>r=!0)),t(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){let u=D(o)?x()-o:void 0;this.logCloseAtEmptyBuffer({duration:u??0}),o=void 0}else r||this.logActionStop()}),t(e.events.managedError$,({id:d})=>{this.logError({fatal:!1,errorType:d})}),t(e.events.fatalError$,({id:d})=>{this.logError({fatal:!0,errorType:d})});let a,n,l=!1;t(e.events.firstBytes$,d=>{a=x(),this.logFirstBytes({time:d})}),t(e.events.willStart$,()=>n=x()),t(e.info.currentBuffer$,d=>{!l&&d&&d.end-d.start>0&&D(a)&&(this.logPlayerReady({duration:x()-a}),l=!0)}),t(e.events.firstFrame$,()=>{D(a)&&!l&&(this.logPlayerReady({duration:x()-a}),l=!0),D(n)&&this.logFirstFrame({time:x()-n})});let c;t(e.info.currentVideoStream$,d=>{d&&(c&&d.id!==c&&this.logTrackSwitch(d),c=d.id)});let h;t(e.info.currentAudioStream$,d=>{d&&(h&&d.id!==h&&this.logTrackSwitch(d),h=d.id)}),t(e.info.atLiveEdge$,d=>this.updateContext({liveEdge:d})),t(Qe({muted:e.info.muted$,volume:e.info.volume$}),({muted:d,volume:u})=>this.updateContext({audible:!d&&u>0})),t(e.info.currentQuality$,d=>{let u=Me(d);this.updateContext({quality:u}),u&&this.logQuality(u)}),t(e.info.isAutoQualityEnabled$,d=>this.updateContext({autoQuality:d})),t(e.info.currentFormat$,d=>this.updateContext({contentType:Ue(d)})),t(e.info.currentPlaybackRate$,d=>this.updateContext({rate:d})),t(e.info.is3DVideo$,d=>this.updateContext({is3d:d}));let p;return t(e.info.hostname$,d=>{let u=p!==void 0&&p!==d;this.updateContext({cdnHostname:d,failover:u}),u&&this.logFailover(d),p=d}),t(e.info.throughputEstimation$,d=>this.updateContext({downloadSpeed:d})),t(e.info.httpConnectionType$,d=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:pe(d)}),this.updateContext({connectionType:pe(d)})}),t(e.info.httpConnectionReused$,d=>{Ge(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:d}),this.updateContext({connectionReused:d})}),t(e.info.surface$,d=>this.updateContext({mode:K(d)})),t(Qe({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:d,available:u})=>{let m=u.find(({id:I})=>I===d),f=m&&(m.isAuto?`${m.language}_auto`:m.language);this.updateContext({subtitles:f?.split(".")[0]})}),this.player=e,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(e){this.uiEvents=e;let{subscription:i,subscribe:t}=me();return this.player&&(t(e.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),t(e.actionSeek$,this.seekAction$),t(e.inPiP$,o=>{let r=o?"pip":K(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),t(e.inFullscreen$,o=>{let r=o?"fullscreen":K(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),t(e.actionSetSubtitle$,o=>this.updateContext({subtitles:o.split(".")[0]})),t(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i)),i}attachToAds(e){let{subscription:i,subscribe:t}=me();return t(e.slotRequested$,()=>this.logAdSlotRequest()),t(e.started$,o=>this.logAdStarted(o)),t(e.paused$,()=>this.logAdPaused()),t(e.resumed$,()=>this.logAdResumed()),t(e.ended$,()=>this.logAdEnded()),t(e.skipped$,()=>this.logAdSkipped()),t(e.clicked$,()=>this.logAdClicked()),t(e.error$,o=>this.logError({errorType:o,fatal:!1})),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToInteractive(e){let{subscription:i,subscribe:t}=me();return t(e.click$,o=>this.logInterfaceClick(o)),t(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i),i}authorize(e){return this.api.authorize(e)}pause(){this.logger.pause(),this.oneStatDebugLog({message:"paused"})}resume(){this.logger.resume(),this.oneStatDebugLog({message:"resumed"})}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.oneStatDebugLog({message:"VSID reset"}),this.vsid$.next(Be())}getDeviceId(){return this.deviceId}setFieldBlacklist(){}logInited(){}logReady(e){this.log({operation:"player_ready",param:String(e.time)})}logStarted(...e){this.logActionPlay(...e)}logPlay(){this.log({operation:"play_toggle"})}logPlaying(){this.log({operation:"playing"})}logPause(e){this.log({operation:"pause",param:String(Math.round(e.position))})}logSeek(e){this.log({operation:"seek",param:e.action,time:e.time})}logFirstBytes(e){this.log({operation:"first_bytes",param:String(e.time)})}logFirstFrame(e){this.log({operation:"first_frame",param:String(e.time)})}logError(e){this.log({operation:"content_error",param:`${e.fatal?"fatal":"recoverable"}_${e.errorType}`})}logWatchCoverageRecord(e){this.log({operation:"watch_coverage_record",param:`${e.start}-${e.end}`},{in_history:this.statContext.inHistory?1:void 0})}logWatchCoverageLive(e){let i=this.timeSynchronisation?.getOffset()??0,t=e.start+i,o=e.end+i;this.log({operation:"watch_coverage_live",param:`${t}-${o}`},{in_history:this.statContext.inHistory?1:void 0,latency:e.latency,buffer_latency:e.bufferLatency})}logEmptyBuffer(e){this.log({operation:"empty_buffer",param:String(e.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(e){this.log({operation:"adv",param:e})}logAdPaused(){this.log({operation:"adv",param:"pause"})}logAdResumed(){this.log({operation:"adv",param:"resume"})}logAdEnded(){this.log({operation:"adv",param:"ended"})}logAdSkipped(){this.log({operation:"adv",param:"skip"})}logAdClicked(){this.log({operation:"adv",param:"click"})}logInterfaceClick(e){this.log({operation:"player_interface_click",param:e})}logNextMovie(e){this.log({operation:"next_movie",param:String(e)})}subscribe(){this.resubscribeBeforeunload();let e=window.navigator.connection;e&&"onchange"in e&&"effectiveType"in e&&this.subscription.add(Kt(je(e,"change"),qt(["init"])).subscribe(()=>this.updateContext({network:Fe(e.effectiveType)}))),this.config.debugLog&&this.debugLogger.log$.subscribe(i=>{console.debug("%c stat ","background:#fa6470;",`component: ${i.component}.`,i.message)})}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=je(window,"beforeunload").subscribe(()=>this.logger.flush({wantBeacon:!0,clearStorage:this.config.clearStorageAtUnload})),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(e){this.log({operation:"player_ready",param:String(Math.round(e.duration))})}logActionPlay(e){this.log({operation:"action_play",param:String(Math.round(e.position))})}logActionPlayInteractive(){this.statContext.projectId&&this.log({operation:"action_play_interactive",param:String(this.statContext.movieId)},{vid:this.statContext.projectId})}logFailover(e){this.log({operation:"failover",param:e})}logCloseAtEmptyBuffer(e){this.log({operation:"close_at_empty_buffer",param:String(Math.round(e.duration))})}logActionStop(){this.log({operation:"action_stop"})}logTrackSwitch(e){this.log({operation:"track_switch",param:e.id})}logQuality(e){this.log({operation:"quality",param:e})}log(e,i={}){if(this.disabled){this.oneStatDebugLog({message:`operation ${e.operation} but statistics is disabled`});return}if(this.config.disabledOperations.includes(e.operation)){this.oneStatDebugLog({message:`operation ${e.operation} but it is disabled`});return}this.oneStatDebugLog({message:`operation ${e.operation} ${e.param}`});let t=this.createLogItem(e,i);this.logger.log(t)}createLogItem({operation:e,param:i,time:t},o={}){let r=this.timeSynchronisation?.now()??x(),a=this.vsid$.getValue();Wt(a);let n=this.isid$.getValue(),l=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,c=this.statContext.firstConnectionReused,h,p;if(this.isEmbed||this.statContext.place==="embed"){h=this.embedParent;let u=[...new URLSearchParams(location.search).entries()].filter(([m,f])=>this.config.embedUrlParams.includes(m));p=new URLSearchParams(u).toString()}else this.statContext.place==="direct"&&(this.statContext.refDomain?h=Xe(this.statContext.refDomain)?.hostname??this.statContext.refDomain:document.referrer&&(h=Xe(document.referrer)?.hostname??document.referrer),p=location.href.substring(0,1024));let d={vsid:a,isid:n,vid:this.statContext.movieId,uid:this.zenUid$.getValue(),ct:this.statContext.contentType,place:this.isEmbed?"embed":this.statContext.place,quality:this.statContext.quality,cdn_host:this.statContext.cdnHostname,stat_type:this.statContext.autoplay===!0?"auto":this.statContext.autoplay===!1?"":void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:l,connection_reused:c===!0?1:c===!1?0:void 0,cached_data:this.statContext.cached===!0?1:this.statContext.cached===!1?0:void 0,live:this.statContext.liveEdge?1:void 0,muted:this.statContext.audible===!1?1:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:1,ref_domain:h,direct_url:p,rate:this.statContext.rate===1||Ge(this.statContext.rate)?void 0:this.statContext.rate.toFixed(2),view_360:this.statContext.is3d?1:void 0,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId,...o};for(let u of this.config.disabledCustomFields)delete d[u];return{operation:e,type:1,time:t,network:this.statContext.network,timestamp:r,custom:d}}};var Pt={};xt(Pt,{SeekType:()=>Q,ThinOneStat:()=>te,VERSION:()=>P});import{assertNonNullable as li,detectEmbed as hi,fromEvent as pi,Logger as fi,merge as vt,safeStorage as It,Subject as gi,Subscription as we,ValueSubject as ee}from"@vkontakte/videoplayer-shared/evergreen";import{clientChecker as L,PlaybackState as St}from"@vkontakte/videoplayer-core/evergreen";import{fillWithDefault as Xt}from"@vkontakte/videoplayer-shared/evergreen";var Q=(n=>(n.SLIDER="slider",n.DOUBLE_TAP="double_tap",n.TIME_CODE="time_code",n.EPISODE="episode",n.REWIND="rewind",n.LIVE="live",n.UNKNOWN="unknown",n))(Q||{});var et="CIOPGQJGDIHBABABA",Ie={prod:"https://api.ok.ru",vk_alias:"https://api.mycdn.me",videotest:"https://videotestapi.ok.ru/api",test:"https://apitest.ok.ru",okcdn:"https://api.okcdn.ru",auto:""};var Jt={apiKey:et,apiEnv:"vk_alias",requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageHeartbeatInterval:15,synchronizeTime:!0,useBeacon:!1,alwaysSendDesktop:!1},tt=s=>Xt(s,Jt);import{getExponentialDelay as Zt,ErrorCategory as N,ValueSubject as ei}from"@vkontakte/videoplayer-shared/evergreen";var j=class{constructor(e){this.params=e,this.authorized$=new ei(!1),this.consequentAuthErrors=0}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this.authorizeWithBackoff()}logBeacon(e){let i="log.logUvStat",t=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,t,o)||this.logRequest(e).catch(()=>{})}async logRequest(e){let i="log.logUvStat",t=this.createLogParams(e),o={},r=this.sessionKey??await this.authorizeWithBackoff();if(!r)return;let a=async(n,l=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,r,o)}catch(c){if(!c||!("error_code"in c)){this.params.error$.next({id:"logRequestUnknown",category:N.NETWORK,message:`Unknown ${i} error`,thrown:c});return}let h=c?.error_code;switch(h){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this.authorizeWithBackoff(),l>0?a(n,l-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this.authorizeWithBackoff(),l>0?a(n,l-1):void 0;default:{this.params.error$.next({id:`LogRequest#${h}`,category:N.EXTERNAL_API,message:`${i} error`,data:c});return}}}};return a(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){return{collector:"ok.mobile.apps.video",uv_stat_data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${P}`,platform:e[0].platform,product:e[0].product,events:e})}}authorizeWithBackoff(){if(!this.consequentAuthErrors)return this.doAuthorize();let e=Zt(this.consequentAuthErrors);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(async()=>{try{let t=await this.doAuthorize();i(t)}catch(t){this.params.error$.next({id:"AuthorizeBackoff",category:N.NETWORK,message:"Otherwise unhandled error in authorization",thrown:t})}finally{this.backoffTimeoutId=0}},e))})}doAuthorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);let e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.deviceId,client_version:P.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(i.session_data.auth_token=this.authToken,i.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,i).then(t=>((!t||!t.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:N.EXTERNAL_API,message:"No session key",data:t}),this.sessionKey=t?.session_key??void 0,this.sessionKey)).catch(async t=>{this.sessionKey=void 0;let o=t?.error_code;switch(o){case 401:return this.authToken=await this.refreshAuthToken(),this.authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:N.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:N.NETWORK,message:"authorize error",thrown:t})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}};import{now as Se,ErrorCategory as G}from"@vkontakte/videoplayer-shared/evergreen";var Y=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=Ie[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}sendBeacon(e,i,t){if(!window.Blob||!window.navigator.sendBeacon)return!1;let o=this.prepareQueryParams({method:e,queryParams:i,sessionKey:t}),r=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,r)}catch(a){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:G.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t,o){let r=Se(),a=n=>{if(n instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(n.message)){this.params.error$.next({id:"Network",category:G.NETWORK,message:"Request failed",thrown:n});return}this.params.error$.next({id:"ThinOneStat:ApiTransport:sendRequest",category:G.NETWORK,message:"Unhandled request error",thrown:n,data:{method:e,params:i,sessionKey:t,time:Se()-r}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),fetch(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded",...o},body:this.prepareQueryParams({method:e,queryParams:i,sessionKey:t})}).then(n=>{let l=Number(n.headers.get("content-length"))===0,c=new Date(n.headers.get("date")??"").getTime(),h=Se()-r;if(isFinite(c)&&this.timeSynchronisation?.addServerTime(c,h),!l)return n.json().then(p=>Object.prototype.hasOwnProperty.call(p,"error_msg")?Promise.reject(p):p,a)},a)}async resolveApiBaseUrl(){if(this.apiEnv!=="auto"||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{let e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(e){return this.params.error$.next({id:"ThinOneStat:ApiTransport:resolveApiBaseUrl",category:G.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),Ie.vk_alias}finally{this.isApiBaseUrlFetched=!0}}prepareQueryParams(e){let i=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&i.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([t,o])=>i.append(t,typeof o=="string"?o:JSON.stringify(o))),i}};import{ErrorCategory as ti,now as ii,safeStorage as F,debounceFn as it}from"@vkontakte/videoplayer-shared/evergreen";var X="thinonestat_events",ye=s=>e=>e.client_time+s>=ii(),J=class{constructor(e){this.unsaltedStorage=[];this.isPaused=!1;this.isUrgent=e=>{let{event_name:i}=e;return["watch_coverage","watch_coverage_live","watched_n","playback_started"].includes(i)};this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=it(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=F.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=it(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(t=>{t&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:ti.WTF,message:String(e)||"Unknown logger error",thrown:e})}}readFromStorage(){let e=F.get(X);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}let i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(ye(this.params.config.storageExpiration));F.set(X,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(ye(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],F.set(X,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(ye(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${t.length} retrieved from storage, ${o.length} of them actual`})}F.set(X,JSON.stringify(e))}log(e){this.addToStorage(e),!this.isPaused&&(this.isUrgent(e)?this.flush():this.lastVsid!==e.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=e.vsid)}flush({wantBeacon:e,clearStorage:i}={wantBeacon:!1,clearStorage:!0}){let t=this.getFromStorage();t.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${t.length} events through beacon`}),this.api.logBeacon(t)):(this.loggerDebugLog({message:`Flushing ${t.length} events`}),this.api.logRequest(t)),i&&this.markStorageSent()):this.api.authorize(),this.firstFlush.cancel(),this.debouncedFlush.cancel())}pause(){this.isPaused=!0,this.debouncedFlush.cancel()}resume(){this.isPaused=!1,this.debouncedFlush()}destroy(){this.subscription.unsubscribe(),this.firstFlush.cancel(),this.debouncedFlush.cancel()}};function Pe(){let s="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36),i=0,t,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),t=i&15,i=i>>4,e[o]=s[o===19?t&3|8:t]);return e.join("")}var Z=class{constructor(e){this.offset=void 0;this.offset=e}getOffset(){return this.offset??0}setOffset(e){this.offset=e}now(){return Date.now()+(this.offset??0)}date(e=new Date){return e.setTime(e.getTime()+(this.offset??0)),e}addServerTime(e,i){let t=Date.now(),o=e-t-i/2;if(Math.abs(o)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(o):this.offset=Math.round(.2*o+(1-.2)*this.offset)}};import{PlaybackState as ot}from"@vkontakte/videoplayer-core/evergreen";import{Observable as oi,Subscription as ri,ValueSubject as si,Subject as _e,fromEvent as ai,isNullable as rt,merge as Ee,filter as st,filterChanged as at}from"@vkontakte/videoplayer-shared/evergreen";var nt=(s,e)=>new oi(i=>{let t=new ri,o=new si(void 0),r;t.add(s.info.isLive$.pipe(at()).subscribe(y=>{r&&(r.unsubscribe(),o.next(void 0)),y?r=s.info.liveTime$.pipe(at()).subscribe(o):r=s.info.position$.subscribe(o),t.add(r)}));let{playing$:a,paused$:n,ended$:l,looped$:c}=s.events,h=s.events.willSeek$.pipe(st(()=>s.info.playbackState$.getValue()===ot.PLAYING)),p=s.events.seeked$.pipe(st(()=>s.info.playbackState$.getValue()===ot.PLAYING)),d=!1,u=new _e;t.add(h.subscribe(()=>{d||u.next(),d=!0})).add(p.subscribe(()=>d=!1));let m=Ee(ai(window,"beforeunload"),s.events.willDestruct$),f,I=()=>f=o.getValue(),S=()=>{let y=o.getValue();rt(f)||rt(y)||f===y||(i.next({from:f,to:y}),f=void 0)},A=new _e,w=new _e,T=Ee(a,u,A),g=Ee(n,p,m,l,c,w);if(t.add(T.subscribe(I)).add(g.subscribe(S)),e.heartbeatInterval&&isFinite(e.heartbeatInterval)){let y=[],At=e.heartbeatInterval*1e3,wt=()=>{w.next(),A.next()};t.add(T.subscribe(()=>{let oe=window.setTimeout(wt,At);y.push(oe)})).add(g.subscribe(()=>{y.forEach(oe=>{window.clearTimeout(oe)}),y=[]}))}return t});import{Subscription as ni}from"@vkontakte/videoplayer-core/evergreen";import{Observable as di}from"@vkontakte/videoplayer-shared/evergreen";var dt=(s,e)=>new di(i=>{let t=new ni,o=1e4,r=0;return t.add(s.info.position$.subscribe(()=>{let a=e.getTotalViewTime()*1e3;a>r&&a%o===0&&(r=a,i.next({target_duration:o,current_tvt:a}))})),t});import{Observable as ci,Subscription as ui,merge as ct}from"@vkontakte/videoplayer-shared/evergreen";var ut=s=>new ci(e=>{let i=new ui,t=0,o=1,r=0,a=!1,n=!1,l=()=>{if(!a)return;let g=Date.now();r+=(g-t)*o,t=g},c=()=>{(!a||n)&&(t=Date.now(),a=!0,n=!1)},h=()=>{a&&(l(),a=!1)},p=()=>{a&&(l(),a=!1,n=!0)},d=g=>{a&&l(),o=g,t=Date.now()},{started$:u,playing$:m,paused$:f,willSeek$:I,ended$:S,willDestruct$:A}=s.events,{currentPlaybackRate$:w}=s.info;i.add(I.subscribe(p)).add(ct(u,m).subscribe(c)).add(ct(f,S,A).subscribe(h)).add(w.subscribe(d));let T=()=>{let g=r;return a&&(g+=(Date.now()-t)*o),Math.floor(g/1e3)};return e.next(T),i});import{assertNever as lt}from"@vkontakte/videoplayer-shared/evergreen";import{Surface as O,VideoFormat as b,VideoQuality as E}from"@vkontakte/videoplayer-core/evergreen";var Ae=s=>{if(s!==void 0)switch(s){case b.MPEG:return"MP4";case b.DASH:case b.DASH_LIVE:return"DASH";case b.DASH_SEP:return"DASH_SEP";case b.DASH_ONDEMAND:return"ONDEMAND_DASH";case b.HLS_ONDEMAND:return"ONDEMAND_HLS";case b.HLS:case b.HLS_LIVE:return"HLS";case b.DASH_WEBM:case b.DASH_LIVE_WEBM:return"WEBM";case b.DASH_LIVE_CMAF:return"ONDEMAND_DASH_LIVE";case b.HLS_LIVE_CMAF:return"ONDEMAND_HLS_LIVE";case b.WEB_RTC_LIVE:return"WEBRTC";case b.DASH_WEBM_AV1:return"AV1";case b.DASH_STREAMS:return"MULTI_DASH";default:return lt(s)}},k=s=>{if(s!==void 0)switch(s){case E.Q_144P:return"144p";case E.Q_240P:return"240p";case E.Q_360P:return"360p";case E.Q_480P:return"480p";case E.Q_720P:return"720p";case E.Q_1080P:return"1080p";case E.Q_1440P:return"1440p";case E.Q_2160P:return"2160p";case E.INVARIANT:case E.Q_576P:case E.Q_4320P:return"UNKNOWN";default:return lt(s)}},ht=s=>{if(s!==void 0)switch(s){case"MP4":case"ONDEMAND_DASH":case"ONDEMAND_DASH_LIVE":case"ONDEMAND_HLS":case"ONDEMAND_HLS_LIVE":case"MULTI_DASH":case"WEBM":case"AV1":return"vod";case"DASH":case"HLS":case"WEBRTC":return"live";default:return}},pt=(s,e,i)=>{if(s&&e)switch(s){case b.MPEG:return i&&e[s]&&e[s][i];default:return e[s]?.url}},ft=s=>{if(s!==void 0)switch(s){case O.NONE:return;case O.INLINE:return"inline";case O.FULLSCREEN:return"fullscreen";case O.SECOND_SCREEN:return"chromecast";case O.PIP:return"pip_external"}},gt=s=>{if(s!==void 0)return s===O.INVISIBLE?"background":"foreground"};var mt=()=>Math.floor(Math.random()*4294967296).toString(36).padStart(13,"0"),bt=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");var mi="_thin-one-stat_",yt=`${mi}deviceId`,bi=()=>{let s=new we;return{subscription:s,subscribe:(e,i)=>{e&&s.add(e.subscribe(i))}}},te=class{constructor(e,i){this.debugLogger=new fi;this.thinOneStatDebugLog=this.debugLogger.createComponentLog("ThinOneStat");this.eventNumber=1;this.seekAction$=new ee("unknown");this.playerSize$=new ee({width:0,height:0});this.vsid$=new ee(void 0);this.isid$=new ee(void 0);this.statContext=e,this.config=tt(i.config??{}),this.subscription=new we,this.config.synchronizeTime&&(this.timeSynchronisation=new Z);let t=new gi,o=It.get(yt);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=Pe(),It.set(yt,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??bt());let r=new Y({error$:t,config:this.config,timeSynchronisation:this.timeSynchronisation});this.api=new j({config:this.config,apiTransport:r,error$:t,deviceId:this.deviceId,refreshAuthToken:i.refreshAuthToken}),this.logger=new J({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:a,topOrigin:n}=hi();this.isEmbed=a,this.embedHostname=n?new URL(n).hostname:void 0}authorize(e){return this.api.authorize(e)}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){let i=new we,t=(r,a)=>i.add(r.subscribe(a));t(ut(e),r=>{this.getTotalViewTime=r}),t(e.info.isLive$,r=>this.isLive=r),t(e.info.position$,r=>this.position=r);let o;return t(e.info.hostname$,r=>{o!==void 0&&o!==r&&this.logFailover({cdn_host:r}),this.cdnHostname=o=r}),t(nt(e,{heartbeatInterval:this.config.watchCoverageHeartbeatInterval}),r=>{let a=Math.round(r.from*1e3),n=Math.round(r.to*1e3),l={watch_interval:`${a}-${n}`,in_history:!!this.statContext.inHistory,content_type:Ae(e.info.currentFormat$.getValue()),playback_quality:k(e.info.currentQuality$.getValue()),recom_info:this.statContext.recomInfo};if(!e.info.isLive$.getValue())this.logWatchCoverage(l);else{let h=e.info.atLiveEdge$.getValue();this.logWatchCoverageLive({...l,live:!!h})}}),t(dt(e,{getTotalViewTime:this.getTotalViewTime}),r=>{this.logWatchedN(r)}),t(vt(e.events.willStart$,e.events.looped$),r=>{r&&this.resetViewSession();let a={isid:this.isid$.getValue(),stream_profile:ht(Ae(e.info.currentFormat$.getValue())),dpi:L.display.pixelRatio,web_layout:L.device.isMobile?"mobile":"desktop",iframe_host:this.isEmbed?this.embedHostname??void 0:null,from_downloads:!0,preloaded:this.statContext.preload,navigation:this.statContext.navigation,recom_info:this.statContext.recomInfo};this.logStartSession(a)}),t(e.events.willReady$,()=>{if(this.statContext.preload){let r=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),n=e.info.currentBuffer$.getValue(),l=e.info.currentQuality$.getValue(),c={target_buffer_time:n?n.end-n.start:void 0,playback_url:pt(r,a,l),playback_quality:k(l)};this.logPreloadStarted(c)}}),t(e.events.ready$,()=>{if(this.statContext.preload){let r=e.info.currentBuffer$.getValue(),a={buffer_time:r?r.end-r.start:void 0};this.logPreloadEnded(a)}}),t(e.events.playing$,()=>{this.logPlay()}),t(e.info.playbackState$,r=>{if(r===St.PLAYING){let a=e.info.currentBuffer$.getValue(),n={buffer_time:a?a.end-a.start:void 0};if(this.logPlaying(n),this.isStarted)this.logResume();else{this.isStarted=!0;let l=e.info.currentQuality$.getValue(),c=e.info.isAutoQualityEnabled$.getValue(),h=e.info.muted$.getValue(),p=e.info.volume$.getValue(),d=e.info.surface$.getValue(),u=e.info.availableTextTracks$.getValue(),m=e.info.currentTextTrack$.getValue(),f=e.info.currentAudioStream$.getValue(),I=e.info.currentPlaybackRate$.getValue(),S={playback_quality:k(l),user_quality:c?"auto":k(l),player_width:this.playerSize$.getValue().width,player_height:this.playerSize$.getValue().height,muted:h,sound_volume:p,buffer_time:a?Math.round(a.end-a.start):void 0,mode:ft(d),visibility:gt(d),subtitles_enabled:!!m,auto_subtitles:!!u.find(({id:A})=>A===m)?.isAuto,audio_track_lang:f?.language,playback_rate:I,recom_info:this.statContext.recomInfo};this.logPlaybackStarted(S)}}else r===St.PAUSED&&this.logPause()}),t(e.events.willSeek$,({to:r})=>{let a={target_position:r,seek_type:this.seekAction$.getValue()};this.logSeeking(a)}),t(e.events.seeked$,()=>{let a={target_position:e.info.position$.getValue(),seek_type:this.seekAction$.getValue()};this.logSeeked(a),this.seekAction$.next("unknown")}),t(vt(e.info.isBuffering$,e.info.isStalled$),r=>{r&&this.logShowLoader()}),t(e.info.currentQuality$,r=>{if(r){let a=e.info.isAutoQualityEnabled$.getValue(),n=e.info.currentVideoStream$.getValue()?.codec,l=e.info.currentAudioStream$.getValue()?.codec,c={user_quality:a?"auto":k(r),playback_quality:k(r),download_quality:k(r),codec_info:n&&l?`${n},${l}`:void 0,manual_switch:!a};this.logQualityChanged(c)}}),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(e){let{subscribe:i,subscription:t}=bi();return i(e.actionSeek$,this.seekAction$),i(e.playerSize$,this.playerSize$),this.subscription.add(t),t}getDeviceId(){return this.deviceId}resetViewSession(){this.thinOneStatDebugLog({message:"VSID reset"}),this.vsid$.next(mt()),this.eventNumber=0}destroy(){this.api.destroy()}createRequiredParams(e){let i=this.vsid$.getValue();li(i);let t=this.eventNumber++;return{vsid:i,uv_movie_id:this.statContext.movieId,event_name:e,client_time:Date.now(),application:`@vkontakte/videoplayer-statistics:${P}`,platform:`web:${L.device.isMobile?"mobile":"desktop"}`,product:this.statContext.product,event_number:t,playback_position:this.isLive?void 0:Math.round(this.position),current_tvt:this.getTotalViewTime(),cdn_host:this.cdnHostname}}createRequiredFatParams(){return{stats_version:P,browser:L.browser.current,browser_version:String(L.browser.currentVersion),os:L.device.current,os_version:"",device_type:L.device.isMobile?"mobile":"desktop",navigation:this.statContext.navigation}}log(e,i,t=!1){let o=this.createRequiredParams(e),r={};t&&(r=this.createRequiredFatParams()),this.logger.log({...o,...r,...i})}logWatchCoverage(e){this.log("watch_coverage",e,!0)}logWatchCoverageLive(e){this.log("watch_coverage_live",e,!0)}logWatchedN(e){this.log("watched_n",e,!0)}logStartSession(e){this.log("start_session",e,!0)}logPreloadStarted(e){this.log("preload_started",e)}logPreloadEnded(e){this.log("preload_ended",e)}logPlaybackStarted(e){this.log("playback_started",e,!0)}logPlay(){this.log("play")}logPlaying(e){this.log("playing",e)}logPause(){this.log("pause")}logResume(){this.log("resume")}logSeeking(e){this.log("seeking",e)}logSeeked(e){this.log("seeked",e)}logShowLoader(){this.log("show_loader")}logQualityChanged(e){this.log("quality_changed",e)}logFailover(e){this.log("failover",e)}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=pi(window,"beforeunload").subscribe(()=>{}),this.subscription.add(this.beforeunloadSubscription)}};var vi={};import{PlaybackState as Et,Subscription as Ii}from"@vkontakte/videoplayer-core/evergreen";import{Logger as Si}from"@vkontakte/videoplayer-shared/evergreen";var ie=class{constructor(){this.startTime=null;this.stopTime=null;this.accumulatedTime=0}get time(){return Math.floor(this.timeMs/1e3)}get timeMs(){return this.startTime===null?0:(this.stopTime??this.now())-this.startTime-this.accumulatedTime}get isRunning(){return this.startTime!==null&&this.stopTime===null}start(){this.isRunning||(this.stopTime!==null?(this.accumulatedTime+=this.now()-this.stopTime,this.stopTime=null):this.startTime=this.now())}stop(){this.isRunning&&(this.stopTime=this.now())}reset(){this.startTime=null,this.stopTime=null,this.accumulatedTime=0}now(){return Date.now()}};var _t=()=>window.Image?new Image:document.createElement("img");var Te=class{constructor(e){this.position=0;this.started=!1;this.heartbeatPixels=[];this.heartbeatLastTimeSent={};this.idleCallbackIds=[];this.stopwatch=new ie;this.subscription=new Ii;this.params=e;let i=new Si;this.log=i.createComponentLog("MediascopePixel")}attachTo(e){this.subscription.add(e.info.playbackState$.subscribe(i=>this.onPlaybackState(i))).add(e.info.position$.subscribe(i=>this.onPosition(i))).add(e.info.atLiveEdge$.subscribe(i=>this.isActiveLive=i)),this.subscription.add(e.events.willSeek$.subscribe(()=>this.onWillSeek())).add(e.events.seeked$.subscribe(()=>this.onSeeked())).add(e.events.ended$.subscribe(()=>this.onEnded()))}destroy(){this.stopwatch.reset(),this.subscription.unsubscribe(),window.clearTimeout(this.heartbeatFirstTimeoutId),this.idleCallbackIds.forEach(e=>window.cancelIdleCallback(e)),this.send("stop")}onPlaybackState(e){e===Et.PLAYING?this.started?this.play():this.start():e===Et.PAUSED&&this.pause()}start(){this.started=!0,this.stopwatch.start(),this.send("start"),this.heartbeatPixels=this.prepareHeartbeatPixels(),this.heartbeatInterval=this.heartbeatPixels[0]?.interval;let e=this.heartbeatPixels[0]?.url,i=this.heartbeatPixels[0]?.delay;if(i!==void 0&&e)try{this.heartbeatFirstTimeoutId=window.setTimeout(()=>{this.sendHeartbeat(e)},i*1e3)}catch(t){this.log({message:t.message})}}play(){this.stopwatch.start(),this.send("resume")}pause(){this.stopwatch.stop(),this.send("pause")}onPosition(e){if(this.position=e,this.heartbeatInterval&&this.stopwatch.time!==0&&this.stopwatch.time%this.heartbeatInterval===0)for(let[i,{url:t}]of this.heartbeatPixels.entries())this.heartbeatLastTimeSent[i]!==this.stopwatch.time&&(this.heartbeatLastTimeSent[i]=this.stopwatch.time,this.sendHeartbeat(t))}onWillSeek(){this.started&&this.send("stop")}onSeeked(){this.started&&this.send("start")}onEnded(){this.stopwatch.stop(),this.send("stop")}validatePixels(e,i){return e?.filter(t=>t.event===i.event&&i.keys.every(o=>!!t[o]))}getFrameTimestamp(){let e;if(this.isActiveLive){let i=Math.floor(Math.random()*25)+5;e=Date.now()/1e3-i}else e=this.position||0;return Math.floor(e)}getUTC(){return Math.floor(Date.now()/1e3)}prepareUrl(e){let i=new URL(e);return i.pathname=i.pathname.replace("{@fts_fake_sec}",String(this.getFrameTimestamp())).replace("{@utc_sec}",String(this.getUTC())),i.search=[...new URLSearchParams(i.search)].filter(([t,o])=>!/={@[\w]+}/.test(`${t}=${o}`)).map(t=>t.join("=")).join("&"),i.toString()}preparePixels(e){return this.validatePixels(this.params.pixels,{event:e,keys:["url"]})}prepareHeartbeatPixels(){return this.validatePixels(this.params.pixels,{event:"heartbeat",keys:["url","interval"]})}call(e){try{this.idleCallbackIds.push(requestIdleCallback(()=>_t().src=this.prepareUrl(e)))}catch(i){this.log({message:i.message})}}send(e){let i=this.preparePixels(e);for(let{url:t}of i)this.call(t)}sendHeartbeat(e){this.call(e)}};export{R as ApiEnv,ae as ConnectionType,se as ContentType,xe as InteractiveInterfaceClick,Te as MediascopePixel,vi as MediascopePixelTypes,ve as OneStat,re as Quality,ne as SeekAction,Pt as ThinOneStat,P as VERSION};
6
+ var Lt=Object.defineProperty;var $t=(r,e)=>{for(var i in e)Lt(r,i,{get:e[i],enumerable:!0})};var F=(l=>(l.PROD="prod",l.VK_ALIAS="vk_alias",l.VIDEOTEST="videotest",l.TEST="test",l.OKCDN="okcdn",l.AUTO="auto",l))(F||{}),de=(a=>(a.Q144P="mobile",a.Q240P="lowest",a.Q360P="low",a.Q480P="medium",a.Q720P="high",a.Q1080P="fullhd",a.Q1440P="quadhd",a.Q2160P="ultrahd",a.UNKNOWN="unknown",a))(de||{}),ce=(g=>(g.MP4="mp4",g.DASH="dash",g.DASH_SEP="dash_sep",g.ONDEMAND_DASH="ondemand_dash",g.HLS="hls",g.HLS_FMP4="hls_fmp4",g.ONDEMAND_HLS="ondemand_hls",g.WEBM="webm",g.AV1="av1",g.ONDEMAND_DASH_LIVE="ondemand_dash_live",g.ONDEMAND_HLS_LIVE="ondemand_hls_live",g.WEBRTC="webrtc",g.UNKNOWN="unknown",g.RTMP="rtmp",g))(ce||{});var le=(t=>(t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3",t))(le||{});var ue=(c=>(c.SLIDER="slider",c.DOUBLE_TAP="double_tap",c.TIME_CODE="time_code",c.EPISODE="episode",c.REWIND="rewind",c.LIVE="live",c.UNKNOWN="unknown",c))(ue||{}),Me=(n=>(n.GRAPH_SHOW="iGraphShow",n.GRAPH_HIDE="iGraphHide",n.NEXT_AREA="iNextChapterArea",n.NEXT_BUTTON="iNextChapterBtn",n.WATCH_AGAIN="iWatchAgainBtn",n))(Me||{}),Fe={action_play:"ap",action_play_interactive:"api",first_bytes:"fb",player_ready:"pr",first_frame:"ff",seek:"sk",watch_coverage_record:"wr",watch_coverage_live:"wl",empty_buffer:"eb",action_stop:"as",close_at_empty_buffer:"cb",content_error:"er",player_interface_click:"pc",next_movie:"nm",track_switch:"ts",failover:"fo",quality:"qt"},Be={vsid:"si",isid:"is",vid:"vi",place:"pl",quality:"qt",cdn_host:"ch",stat_type:"st",param:"pm",vk_app_id:"va",track_code:"tc",connection_type:"cnt",connection_reused:"cr",cached_data:"cd",live:"lv",muted:"mu",mode:"mo",subtitles:"sb",failover:"fo",download_speed:"ds",manual_quality:"mq",ref_domain:"rd",direct_url:"du"},Ue={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},He={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv",minimal:"minimal"};import{fillWithDefault as Rt}from"@vkontakte/videoplayer-shared/evergreen";var qe="CIOPGQJGDIHBABABA",he={prod:"https://api.ok.ru",vk_alias:"https://api.mycdn.me",videotest:"https://videotestapi.ok.ru/api",test:"https://apitest.ok.ru",okcdn:"https://api.okcdn.ru",auto:""};var Dt={apiEnv:"vk_alias",apiKey:qe,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageInterval:15e3,disabledOperations:["quality"],disabledCustomFields:[],shorten:!0,maxLoops:100,embedUrlParams:[],useBeacon:!0,synchronizeTime:!0,debugLog:!1,clearStorageAtUnload:!0,useVKComIsMobileLogic:!1,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1},useKeepalive:!1},We=r=>Rt(r,Dt);function pe(){let r="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36),i=0,t,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),t=i&15,i=i>>4,e[o]=r[o===19?t&3|8:t]);return e.join("")}import{assertNonNullable as jt,combine as it,fromEvent as ot,isNonNullable as O,isNullable as rt,merge as Gt,now as x,observableFrom as Yt,once as Xt,safeStorage as st,Subject as Jt,Subscription as Se,ValueSubject as Y}from"@vkontakte/videoplayer-shared/evergreen";import{Logger as Zt,detectEmbed as ei}from"@vkontakte/videoplayer-shared/evergreen";var Nt=()=>Math.floor(Math.random()*4294967296).toString(36).padStart(13,"0"),k=class r{static getVSID(){return r.vsid}static generateVSID(){return r.vsid=Nt(),r.vsid}};var Ke=r=>{let{operation:e,custom:i}=r,t=Object.fromEntries(Object.entries(i).map(([o,n])=>{let l=Be[o]??o,c=n;return n&&(o==="mode"?c=He[n]??n:o==="quality"&&(c=Ue[n]??n)),[l,c]}));return{...r,operation:Fe[e]??e,custom:t}};var S="1.0.84-beta.0";import{ValueSubject as Ot,getExponentialDelay as Vt,ErrorCategory as D}from"@vkontakte/videoplayer-shared/evergreen";var Mt=/Mobile|mini|Fennec|Android|iP(ad|od|hone)|opera (mini|mobi)/i,B=class{constructor(e){this.consequentAuthErrors=0;this.authorized$=new Ot(!1);this.params=e}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(e){let i="log.externalLog",t=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,t,o)||this.logRequest(e).catch(()=>{})}async logRequest(e){let i="log.externalLog",t=this.createLogParams(e),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;let n=async(l,c=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,o)}catch(s){if(!s||!("error_code"in s)){this.params.error$.next({id:"logRequestUnknown",category:D.NETWORK,message:`Unknown ${i} error`,thrown:s});return}let a=s?.error_code;switch(a){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),c>0?n(l,c-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),c>0?n(l,c-1):void 0;default:{this.params.error$.next({id:`LogRequest#${a}`,category:D.EXTERNAL_API,message:`${i} error`,data:s});return}}}};return n(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){let i="WEB",t=!1,o=`@vkontakte/videoplayer-statistics:${S}`;if(this.params.config.useVKComIsMobileLogic){let{appVersion:n}=window.navigator;t=Mt.test(n)}else this.params.mobile&&(t=!0);return t&&(i="M_WEB"),this.params.vktvVersion&&(i="SMART_TV",o=this.params.vktvVersion),{collector:"ok.mobile.apps.video",data:JSON.stringify({application:o,platform:i,items:this.params.config.shorten?e.map(Ke):e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();let e=Vt(this.consequentAuthErrors,this.params.config.backoff);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(t=>this.params.error$.next({id:"AuthorizeBackoff",category:D.NETWORK,message:"Otherwise unhandled error in authorization",thrown:t})).finally(()=>this.backoffTimeoutId=0)},e))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);let e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.deviceId,client_version:S.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(i.session_data.auth_token=this.authToken,i.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,i).then(t=>((!t||!t.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:D.EXTERNAL_API,message:"No session key",data:t}),this.sessionKey=t?.session_key??void 0,this.sessionKey)).catch(async t=>{this.sessionKey=void 0;let o=t?.error_code;switch(o){case 401:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:D.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:D.NETWORK,message:"authorize error",thrown:t})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}};import{ErrorCategory as K,now as ge}from"@vkontakte/videoplayer-shared/evergreen";var U=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=he[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!=="auto"||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{let e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(e){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:K.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),he.vk_alias}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(e,i,t){if(!window.Blob||!window.navigator.sendBeacon)return!1;let o=this._prepareQueryParams({method:e,queryParams:i,sessionKey:t}),n=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,n)}catch(l){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:K.NETWORK,message:"Unhandled beacon error",thrown:l,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t){let o=ge(),n=c=>{if(c instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(c.message)){this.params.error$.next({id:"Network",category:K.NETWORK,message:"Request failed",thrown:c});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:K.NETWORK,message:"Unhandled request error",thrown:c,data:{method:e,params:i,sessionKey:t,time:ge()-o}})};this.apiBaseUrl=await this.resolveApiBaseUrl();let l={method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:i,sessionKey:t})};return this.params.config.useKeepalive&&(l.keepalive=!0),fetch(`${this.apiBaseUrl}/fb.do`,l).then(c=>{let s=Number(c.headers.get("content-length"))===0,a=new Date(c.headers.get("date")??"").getTime(),u=ge()-o;if(isFinite(a)&&this.timeSynchronisation?.addServerTime(a,u),!s)return c.json().then(h=>Object.prototype.hasOwnProperty.call(h,"error_msg")?Promise.reject(h):h,n)},n)}_prepareQueryParams(e){let i=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&i.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([t,o])=>i.append(t,typeof o=="string"?o:JSON.stringify(o))),i}};import{ErrorCategory as Ft,now as Bt,safeStorage as H,debounceFn as Qe}from"@vkontakte/videoplayer-shared/evergreen";var Q="onestat_events",fe=r=>e=>e.timestamp+r>=Bt(),z=class{constructor(e){this.unsaltedStorage=[];this.isPaused=!1;this.isUrgent=e=>{let{operation:i}=e;return["action_play","watch_coverage_record","watch_coverage_live"].includes(i)};this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=Qe(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=H.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=Qe(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(t=>{t&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:Ft.WTF,message:e?String(e):"Unknown logger error",thrown:e})}}readFromStorage(){let e=H.get(Q);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}let i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(fe(this.params.config.storageExpiration));H.set(Q,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(fe(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],H.set(Q,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(fe(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${t.length} retrieved from storage, ${o.length} of them actual`})}H.set(Q,JSON.stringify(e))}log(e){this.addToStorage(e),!this.isPaused&&(this.isUrgent(e)?this.flush():this.lastVsid!==e.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=e.custom.vsid)}flush({wantBeacon:e,clearStorage:i}={wantBeacon:!1,clearStorage:!0}){let t=this.getFromStorage();t.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${t.length} events through beacon`}),this.api.logBeacon(t)):(this.loggerDebugLog({message:`Flushing ${t.length} events`}),this.api.logRequest(t)),i&&this.markStorageSent()):this.api.authorize(),this.firstFlush.cancel(),this.debouncedFlush.cancel())}pause(){this.isPaused=!0,this.debouncedFlush.cancel()}resume(){this.isPaused=!1,this.debouncedFlush()}destroy(){this.subscription.unsubscribe(),this.firstFlush.cancel(),this.debouncedFlush.cancel()}};import{HttpConnectionType as me,Surface as N,VideoFormat as I,VideoQuality as A}from"@vkontakte/videoplayer-core/evergreen";import{assertNever as ze}from"@vkontakte/videoplayer-shared/evergreen";var je=r=>r&&{[A.INVARIANT]:"unknown",[A.Q_144P]:"mobile",[A.Q_240P]:"lowest",[A.Q_360P]:"low",[A.Q_480P]:"medium",[A.Q_576P]:"unknown",[A.Q_720P]:"high",[A.Q_1080P]:"fullhd",[A.Q_1440P]:"quadhd",[A.Q_2160P]:"ultrahd",[A.Q_4320P]:"unknown"}[r],ve=r=>r&&{[me.HTTP1]:"http1",[me.HTTP2]:"http2",[me.QUIC]:"http3"}[r],Ge=r=>{if(r!==void 0)switch(r){case I.MPEG:return"mp4";case I.DASH:case I.DASH_LIVE:case I.DASH_STREAMS:return"dash";case I.DASH_SEP:return"dash_sep";case I.DASH_ONDEMAND:return"ondemand_dash";case I.DASH_WEBM:case I.DASH_LIVE_WEBM:return"webm";case I.DASH_WEBM_AV1:return"av1";case I.DASH_LIVE_CMAF:return"ondemand_dash_live";case I.HLS:case I.HLS_LIVE:return"hls";case I.HLS_FMP4:return"hls_fmp4";case I.HLS_ONDEMAND:return"ondemand_hls";case I.HLS_LIVE_CMAF:return"ondemand_hls_live";case I.WEB_RTC_LIVE:return"webrtc";default:return ze(r)}},j=(r,e)=>{if(e)return"minimal";if(r!==void 0)switch(r){case N.NONE:case N.INLINE:return;case N.FULLSCREEN:return"fullscreen";case N.SECOND_SCREEN:return"chromecast";case N.PIP:return"pip";case N.INVISIBLE:return"invisible";default:return ze(r)}},Ye=r=>{switch(r){case"slow-2g":return"poor";case"2g":return"poor";case"3g":return"good";case"4g":return"excellent"}};var G=class{constructor(e){this.offset=void 0;this.offset=e}getOffset(){return this.offset??0}setOffset(e){this.offset=e}now(){return Date.now()+(this.offset??0)}date(e=new Date){return e.setTime(e.getTime()+(this.offset??0)),e}addServerTime(e,i){let t=Date.now(),o=e-t-i/2;if(Math.abs(o)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(o):this.offset=Math.round(.2*o+(1-.2)*this.offset)}};var Xe=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");import{PlaybackState as Je}from"@vkontakte/videoplayer-core/evergreen";import{filter as Ze,filterChanged as Ht,fromEvent as qt,isNullable as et,map as Wt,merge as be,Observable as Kt,Subject as Ie,Subscription as Qt,ValueSubject as zt}from"@vkontakte/videoplayer-shared/evergreen";var tt=(r,e)=>new Kt(i=>{let t=new Qt,o=be(qt(window,"beforeunload"),r.events.willDestruct$),n=new zt(void 0),l;t.add(r.info.isLive$.pipe(Ht()).subscribe(f=>{l&&(l.unsubscribe(),n.next(void 0)),f?l=r.info.liveTime$.pipe(Wt(R=>R&&R/1e3)).subscribe(n):l=r.info.position$.subscribe(n),t.add(l)}));let{playing$:c,paused$:s}=r.events,a=r.events.willSeek$.pipe(Ze(()=>r.info.playbackState$.getValue()===Je.PLAYING)),u=r.events.seeked$.pipe(Ze(()=>r.info.playbackState$.getValue()===Je.PLAYING)),h=!1,d=new Ie;t.add(a.subscribe(()=>{h||d.next(),h=!0})),t.add(u.subscribe(()=>h=!1));let p=new Ie,g=new Ie,m=be(c,u,p),v=be(s,d,o,r.events.looped$,g),y,T=()=>y=n.getValue(),_=()=>{let f=n.getValue();et(y)||y===f||et(f)||(i.next({from:y,to:f}),y=void 0)},P=()=>{g.next(),p.next()};if(t.add(m.subscribe(T)),t.add(v.subscribe(_)),e.forceInterval&&isFinite(e.forceInterval)){let f=0;t.add(m.subscribe(()=>f=window.setTimeout(P,e.forceInterval))),t.add(v.subscribe(()=>window.clearTimeout(f)))}return t});var ti="_one-stat_",nt=`${ti}deviceId`,ye=()=>{let r=new Se;return{subscription:r,subscribe:(e,i)=>{e&&r.add(e.subscribe(i))}}},_e=class{constructor(e,i){this.subscription=new Se;this.debugLogger=new Zt;this.oneStatDebugLog=this.debugLogger.createComponentLog("onestat");this.loopCounter=0;this.disabled=!1;this.isid$=new Y(void 0);this.zenUid$=new Y(void 0);this.seekAction$=new Y("unknown");this.statContext=e,this.config=We(i.config??{}),O(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new G);let t=new Jt;this.experimental={error$:t};let o=st.get(nt);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=pe(),st.set(nt,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??Xe()),this.zenUid$.next(i.zenUid);let n=new U({config:this.config,error$:t,timeSynchronisation:this.timeSynchronisation});this.api=new B({config:this.config,apiTransport:n,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,deviceId:this.deviceId,error$:t,vktvVersion:i.vktvVersion}),this.logger=new z({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:l,topOrigin:c}=ei();this.isEmbed=l,this.embedParent=c?new URL(c).hostname:void 0,this.subscribe()}get vsid$(){return new Y(k.getVSID())}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){let i=new Se,t=(d,p)=>i.add(d.subscribe(p));t(e.events.willStart$,()=>{let d=e.info.position$.getValue();this.logActionPlay({position:d}),this.statContext.projectId&&this.logActionPlayInteractive()}),t(e.events.looped$,()=>{this.resetViewSession(),++this.loopCounter>this.config.maxLoops&&(this.disabled=!0),this.logActionPlay({position:e.info.position$.getValue()})}),t(e.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:e.info.position$.getValue()}),this.seekAction$.next("unknown")}),t(e.events.paused$,()=>{this.logPause({position:e.info.position$.getValue()})}),t(e.events.willResume$,()=>{this.logPlay()}),t(e.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),t(e.events.playing$,()=>{this.logPlaying()}),t(tt(e,{forceInterval:this.config.watchCoverageInterval}),d=>{let p=e.info.isLive$.getValue(),g=e.info.atLiveEdge$.getValue(),m={start:parseFloat(d.from.toFixed(3)),end:parseFloat(d.to.toFixed(3))};if(g){let v=e.info.liveLatency$.getValue()??0,y=e.info.currentBuffer$.getValue()?.end??0,T=e.info.liveBufferTime$.getValue()??0,_=Math.round((v-(y-T))*1e3),P=Math.round(v*1e3);_&&P&&(m.latency=_,m.bufferLatency=P)}p?this.logWatchCoverageLive(m):this.logWatchCoverageRecord(m)});let o;t(e.info.isStalled$,d=>{d?o=x():(O(o)&&this.logEmptyBuffer({duration:x()-o}),o=void 0)});let n=!1;i.add(e.events.fatalError$.pipe(Xt()).subscribe(()=>n=!0)),t(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){let p=O(o)?x()-o:void 0;this.logCloseAtEmptyBuffer({duration:p??0}),o=void 0}else n||this.logActionStop()}),t(e.events.managedError$,({id:d})=>{this.logError({fatal:!1,errorType:d})}),t(e.events.fatalError$,({id:d})=>{this.logError({fatal:!0,errorType:d})});let l,c,s=!1;t(e.events.firstBytes$,d=>{l=x(),this.logFirstBytes({time:d})}),t(e.events.willStart$,()=>c=x()),t(e.info.currentBuffer$,d=>{!s&&d&&d.end-d.start>0&&O(l)&&(this.logPlayerReady({duration:x()-l}),s=!0)}),t(e.events.firstFrame$,()=>{O(l)&&!s&&(this.logPlayerReady({duration:x()-l}),s=!0),O(c)&&this.logFirstFrame({time:x()-c})});let a;t(e.info.currentVideoStream$,d=>{d&&(a&&d.id!==a&&this.logTrackSwitch(d),a=d.id)});let u;t(e.info.currentAudioStream$,d=>{d&&(u&&d.id!==u&&this.logTrackSwitch(d),u=d.id)}),t(e.info.atLiveEdge$,d=>this.updateContext({liveEdge:d})),t(it({muted:e.info.muted$,volume:e.info.volume$}),({muted:d,volume:p})=>this.updateContext({audible:!d&&p>0})),t(e.info.currentQuality$,d=>{let p=je(d);this.updateContext({quality:p}),p&&this.logQuality(p)}),t(e.info.isAutoQualityEnabled$,d=>this.updateContext({autoQuality:d})),t(e.info.currentFormat$,d=>this.updateContext({contentType:Ge(d)})),t(e.info.currentPlaybackRate$,d=>this.updateContext({rate:d})),t(e.info.is3DVideo$,d=>this.updateContext({is3d:d}));let h;return t(e.info.hostname$,d=>{let p=h!==void 0&&h!==d;this.updateContext({cdnHostname:d,failover:p}),p&&this.logFailover(d),h=d}),t(e.info.throughputEstimation$,d=>this.updateContext({downloadSpeed:d})),t(e.info.httpConnectionType$,d=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:ve(d)}),this.updateContext({connectionType:ve(d)})}),t(e.info.httpConnectionReused$,d=>{rt(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:d}),this.updateContext({connectionReused:d})}),t(e.info.surface$,d=>this.updateContext({mode:j(d,this.statContext.isPreviewPlayerView)})),t(it({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:d,available:p})=>{let g=p.find(({id:v})=>v===d),m=g&&(g.isAuto?`${g.language}_auto`:g.language);this.updateContext({subtitles:m?.split(".")[0]})}),this.player=e,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(e){this.uiEvents=e;let{subscription:i,subscribe:t}=ye();return this.player&&(t(e.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),t(e.actionSeek$,this.seekAction$),t(e.inPiP$,o=>{let n=o?"pip":j(this.player?.info.surface$.getValue(),this.statContext.isPreviewPlayerView);this.updateContext({mode:n})}),t(e.inFullscreen$,o=>{let n=o?"fullscreen":j(this.player?.info.surface$.getValue(),this.statContext.isPreviewPlayerView);this.updateContext({mode:n})}),t(e.actionSetSubtitle$,o=>this.updateContext({subtitles:o.split(".")[0]})),t(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i)),i}attachToAds(e){let{subscription:i,subscribe:t}=ye();return t(e.slotRequested$,()=>this.logAdSlotRequest()),t(e.started$,o=>this.logAdStarted(o)),t(e.paused$,()=>this.logAdPaused()),t(e.resumed$,()=>this.logAdResumed()),t(e.ended$,()=>this.logAdEnded()),t(e.skipped$,()=>this.logAdSkipped()),t(e.clicked$,()=>this.logAdClicked()),t(e.error$,o=>this.logError({errorType:o,fatal:!1})),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToInteractive(e){let{subscription:i,subscribe:t}=ye();return t(e.click$,o=>this.logInterfaceClick(o)),t(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i),i}authorize(e){return this.api.authorize(e)}pause(){this.logger.pause(),this.oneStatDebugLog({message:"paused"})}resume(){this.logger.resume(),this.oneStatDebugLog({message:"resumed"})}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.oneStatDebugLog({message:"VSID reset"}),k.generateVSID()}getDeviceId(){return this.deviceId}setFieldBlacklist(){}logInited(){}logReady(e){this.log({operation:"player_ready",param:String(e.time)})}logStarted(...e){this.logActionPlay(...e)}logPlay(){this.log({operation:"play_toggle"})}logPlaying(){this.log({operation:"playing"})}logPause(e){this.log({operation:"pause",param:String(Math.round(e.position))})}logSeek(e){this.log({operation:"seek",param:e.action,time:e.time})}logFirstBytes(e){this.log({operation:"first_bytes",param:String(e.time)})}logFirstFrame(e){this.log({operation:"first_frame",param:String(e.time)})}logError(e){this.log({operation:"content_error",param:`${e.fatal?"fatal":"recoverable"}_${e.errorType}`})}logWatchCoverageRecord(e){this.log({operation:"watch_coverage_record",param:`${e.start}-${e.end}`},{in_history:this.statContext.inHistory?1:void 0})}logWatchCoverageLive(e){let i=this.timeSynchronisation?.getOffset()??0,t=e.start+i,o=e.end+i;this.log({operation:"watch_coverage_live",param:`${t}-${o}`},{in_history:this.statContext.inHistory?1:void 0,latency:e.latency,buffer_latency:e.bufferLatency})}logEmptyBuffer(e){this.log({operation:"empty_buffer",param:String(e.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(e){this.log({operation:"adv",param:e})}logAdPaused(){this.log({operation:"adv",param:"pause"})}logAdResumed(){this.log({operation:"adv",param:"resume"})}logAdEnded(){this.log({operation:"adv",param:"ended"})}logAdSkipped(){this.log({operation:"adv",param:"skip"})}logAdClicked(){this.log({operation:"adv",param:"click"})}logInterfaceClick(e){this.log({operation:"player_interface_click",param:e})}logNextMovie(e){this.log({operation:"next_movie",param:String(e)})}subscribe(){this.resubscribeBeforeunload();let e=window.navigator.connection;e&&"onchange"in e&&"effectiveType"in e&&this.subscription.add(Gt(ot(e,"change"),Yt(["init"])).subscribe(()=>this.updateContext({network:Ye(e.effectiveType)}))),this.config.debugLog&&this.debugLogger.log$.subscribe(i=>{console.debug("%c stat ","background:#fa6470;",`component: ${i.component}.`,i.message)})}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=ot(window,"beforeunload").subscribe(()=>this.logger.flush({wantBeacon:!0,clearStorage:this.config.clearStorageAtUnload})),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(e){this.log({operation:"player_ready",param:String(Math.round(e.duration))})}logActionPlay(e){this.log({operation:"action_play",param:String(Math.round(e.position))})}logActionPlayInteractive(){this.statContext.projectId&&this.log({operation:"action_play_interactive",param:String(this.statContext.movieId)},{vid:this.statContext.projectId})}logFailover(e){this.log({operation:"failover",param:e})}logCloseAtEmptyBuffer(e){this.log({operation:"close_at_empty_buffer",param:String(Math.round(e.duration))})}logActionStop(){this.log({operation:"action_stop"})}logTrackSwitch(e){this.log({operation:"track_switch",param:e.id})}logQuality(e){this.log({operation:"quality",param:e})}log(e,i={}){if(this.disabled){this.oneStatDebugLog({message:`operation ${e.operation} but statistics is disabled`});return}if(this.config.disabledOperations.includes(e.operation)){this.oneStatDebugLog({message:`operation ${e.operation} but it is disabled`});return}this.oneStatDebugLog({message:`operation ${e.operation} ${e.param}`});let t=this.createLogItem(e,i);this.logger.log(t)}createLogItem({operation:e,param:i,time:t},o={}){let n=this.timeSynchronisation?.now()??x(),l=this.vsid$.getValue();jt(l);let c=this.isid$.getValue(),s=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,a=this.statContext.firstConnectionReused,u,h;if(this.isEmbed||this.statContext.place==="embed"){u=this.embedParent;let p=[...new URLSearchParams(location.search).entries()].filter(([g,m])=>this.config.embedUrlParams.includes(g));h=new URLSearchParams(p).toString()}else if(this.statContext.place==="direct"){let p=this.statContext.refDomain||document.referrer;p&&URL.canParse(p)?u=new URL(p).hostname:u=p,h=location.href.substring(0,1024)}let d={vsid:l,isid:c,vid:this.statContext.movieId,uid:this.zenUid$.getValue(),ct:this.statContext.contentType,place:this.isEmbed?"embed":this.statContext.place,quality:this.statContext.quality,cdn_host:this.statContext.cdnHostname,stat_type:this.statContext.autoplay===!0?"auto":this.statContext.autoplay===!1?"":void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:s,connection_reused:a===!0?1:a===!1?0:void 0,cached_data:this.statContext.cached===!0?1:this.statContext.cached===!1?0:void 0,live:this.statContext.liveEdge?1:void 0,muted:this.statContext.audible===!1?1:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:1,ref_domain:u,direct_url:h,rate:this.statContext.rate===1||rt(this.statContext.rate)?void 0:this.statContext.rate.toFixed(2),view_360:this.statContext.is3d?1:void 0,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId,...o};for(let p of this.config.disabledCustomFields)delete d[p];return{operation:e,type:1,time:t,network:this.statContext.network,timestamp:n,custom:d}}};var Tt={};$t(Tt,{SeekType:()=>X,ThinOneStat:()=>se,VERSION:()=>S});import{assertNonNullable as mi,detectEmbed as vi,fromEvent as bi,Logger as Ii,merge as $e,combine as yi,filter as Si,filterChanged as _i,safeStorage as _t,Subject as Pi,Subscription as De,ValueSubject as Re}from"@vkontakte/videoplayer-shared/evergreen";import{clientChecker as $,PlaybackState as Pt}from"@vkontakte/videoplayer-core/evergreen";import{fillWithDefault as ii}from"@vkontakte/videoplayer-shared/evergreen";var X=(c=>(c.SLIDER="slider",c.DOUBLE_TAP="double_tap",c.TIME_CODE="time_code",c.EPISODE="episode",c.REWIND="rewind",c.LIVE="live",c.UNKNOWN="unknown",c))(X||{});var dt="CIOPGQJGDIHBABABA",Pe={prod:"https://api.ok.ru",vk_alias:"https://api.mycdn.me",videotest:"https://videotestapi.ok.ru/api",test:"https://apitest.ok.ru",okcdn:"https://api.okcdn.ru",auto:""};var oi={apiKey:dt,apiEnv:"okcdn",requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageHeartbeatInterval:30,synchronizeTime:!0,useBeacon:!1,alwaysSendDesktop:!1},ct=r=>ii(r,oi);import{getExponentialDelay as ri,ErrorCategory as V,ValueSubject as si}from"@vkontakte/videoplayer-shared/evergreen";var J=class{constructor(e){this.params=e,this.authorized$=new si(!1),this.consequentAuthErrors=0}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this.authorizeWithBackoff()}logBeacon(e){let i="log.logUvStat",t=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,t,o)||this.logRequest(e).catch(()=>{})}async logRequest(e){let i="log.logUvStat",t=this.createLogParams(e),o={},n=this.sessionKey??await this.authorizeWithBackoff();if(!n)return;let l=async(c,s=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,n,o)}catch(a){if(!a||!("error_code"in a)){this.params.error$.next({id:"logRequestUnknown",category:V.NETWORK,message:`Unknown ${i} error`,thrown:a});return}let u=a?.error_code;switch(u){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this.authorizeWithBackoff(),s>0?l(c,s-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this.authorizeWithBackoff(),s>0?l(c,s-1):void 0;default:{this.params.error$.next({id:`LogRequest#${u}`,category:V.EXTERNAL_API,message:`${i} error`,data:a});return}}}};return l(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){return{collector:"ok.mobile.apps.video",uv_stat_data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${S}`,platform:e[0].platform,product:e[0].product,events:e})}}authorizeWithBackoff(){if(!this.consequentAuthErrors)return this.doAuthorize();let e=ri(this.consequentAuthErrors);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(async()=>{try{let t=await this.doAuthorize();i(t)}catch(t){this.params.error$.next({id:"AuthorizeBackoff",category:V.NETWORK,message:"Otherwise unhandled error in authorization",thrown:t})}finally{this.backoffTimeoutId=0}},e))})}doAuthorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);let e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.deviceId,client_version:S.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(i.session_data.auth_token=this.authToken,i.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,i).then(t=>((!t||!t.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:V.EXTERNAL_API,message:"No session key",data:t}),this.sessionKey=t?.session_key??void 0,this.sessionKey)).catch(async t=>{this.sessionKey=void 0;let o=t?.error_code;switch(o){case 401:return this.authToken=await this.refreshAuthToken(),this.authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:V.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:V.NETWORK,message:"authorize error",thrown:t})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}};import{now as Ae,ErrorCategory as Z}from"@vkontakte/videoplayer-shared/evergreen";var ee=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=Pe[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}sendBeacon(e,i,t){if(!window.Blob||!window.navigator.sendBeacon)return!1;let o=this.prepareQueryParams({method:e,queryParams:i,sessionKey:t}),n=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,n)}catch(l){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:Z.NETWORK,message:"Unhandled beacon error",thrown:l,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t,o){let n=Ae(),l=c=>{if(c instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(c.message)){this.params.error$.next({id:"Network",category:Z.NETWORK,message:"Request failed",thrown:c});return}this.params.error$.next({id:"ThinOneStat:ApiTransport:sendRequest",category:Z.NETWORK,message:"Unhandled request error",thrown:c,data:{method:e,params:i,sessionKey:t,time:Ae()-n}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),fetch(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded",...o},body:this.prepareQueryParams({method:e,queryParams:i,sessionKey:t})}).then(c=>{let s=Number(c.headers.get("content-length"))===0,a=new Date(c.headers.get("date")??"").getTime(),u=Ae()-n;if(isFinite(a)&&this.timeSynchronisation?.addServerTime(a,u),!s)return c.json().then(h=>Object.prototype.hasOwnProperty.call(h,"error_msg")?Promise.reject(h):h,l)},l)}async resolveApiBaseUrl(){if(this.apiEnv!=="auto"||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{let e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(e){return this.params.error$.next({id:"ThinOneStat:ApiTransport:resolveApiBaseUrl",category:Z.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),Pe.vk_alias}finally{this.isApiBaseUrlFetched=!0}}prepareQueryParams(e){let i=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&i.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([t,o])=>i.append(t,typeof o=="string"?o:JSON.stringify(o))),i}};import{ErrorCategory as ni,now as ai,safeStorage as q,debounceFn as lt}from"@vkontakte/videoplayer-shared/evergreen";var te="thinonestat_events",Ee=r=>e=>e.client_time+r>=ai(),ie=class{constructor(e){this.unsaltedStorage=[];this.isPaused=!1;this.isUrgent=e=>{let{event_name:i}=e;return["watch_coverage","watch_coverage_live","watched_n","playback_started"].includes(i)};this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=lt(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=q.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=lt(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(t=>{t&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:ni.WTF,message:String(e)||"Unknown logger error",thrown:e})}}readFromStorage(){let e=q.get(te);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}let i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(Ee(this.params.config.storageExpiration));q.set(te,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(Ee(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],q.set(te,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(Ee(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${t.length} retrieved from storage, ${o.length} of them actual`})}q.set(te,JSON.stringify(e))}log(e){this.addToStorage(e),!this.isPaused&&(this.isUrgent(e)?this.flush():this.lastVsid!==e.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=e.vsid)}flush({wantBeacon:e,clearStorage:i}={wantBeacon:!1,clearStorage:!0}){let t=this.getFromStorage();t.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${t.length} events through beacon`}),this.api.logBeacon(t)):(this.loggerDebugLog({message:`Flushing ${t.length} events`}),this.api.logRequest(t)),i&&this.markStorageSent()):this.api.authorize(),this.firstFlush.cancel(),this.debouncedFlush.cancel())}pause(){this.isPaused=!0,this.debouncedFlush.cancel()}resume(){this.isPaused=!1,this.debouncedFlush()}destroy(){this.subscription.unsubscribe(),this.firstFlush.cancel(),this.debouncedFlush.cancel()}};function Te(){let r="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36),i=0,t,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),t=i&15,i=i>>4,e[o]=r[o===19?t&3|8:t]);return e.join("")}var oe=class{constructor(e){this.offset=void 0;this.offset=e}getOffset(){return this.offset??0}setOffset(e){this.offset=e}now(){return Date.now()+(this.offset??0)}date(e=new Date){return e.setTime(e.getTime()+(this.offset??0)),e}addServerTime(e,i){let t=Date.now(),o=e-t-i/2;if(Math.abs(o)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(o):this.offset=Math.round(.2*o+(1-.2)*this.offset)}};import{PlaybackState as ut}from"@vkontakte/videoplayer-core/evergreen";import{Observable as di,Subscription as ci,ValueSubject as li,Subject as we,fromEvent as ui,isNullable as ht,merge as W,filter as pt,filterChanged as gt}from"@vkontakte/videoplayer-shared/evergreen";var ft=(r,e,i)=>new di(t=>{let o=new ci,n=new li(void 0),l;o.add(r.info.isLive$.pipe(gt()).subscribe(w=>{l&&(l.unsubscribe(),n.next(void 0)),w?l=r.info.liveTime$.pipe(gt()).subscribe(n):l=r.info.position$.subscribe(n),o.add(l)}));let{playing$:c,paused$:s,ended$:a,looped$:u}=r.events,h=r.events.willSeek$.pipe(pt(()=>r.info.playbackState$.getValue()===ut.PLAYING)),d=r.events.seeked$.pipe(pt(()=>r.info.playbackState$.getValue()===ut.PLAYING)),p=!1,g=new we;o.add(h.subscribe(()=>{p||g.next(),p=!0})).add(d.subscribe(()=>p=!1));let m=W(ui(window,"beforeunload"),r.events.willDestruct$),v,y=()=>v=n.getValue(),T=()=>{let w=n.getValue();ht(v)||ht(w)||v===w||(t.next({from:v,to:w}),v=void 0)},_=new we,P=new we,f=W(c,g,_),R=W(s,d,m,a,u,P),Oe=e.started$&&e.ended$?W(f,e.ended$):f,Ve=e.started$&&e.ended$?W(R,e.started$):R;if(o.add(Oe.subscribe(y)).add(Ve.subscribe(T)),i.heartbeatInterval&&isFinite(i.heartbeatInterval)){let w=[],kt=i.heartbeatInterval*1e3,Ct=()=>{P.next(),_.next()};o.add(Oe.subscribe(()=>{let ae=window.setTimeout(Ct,kt);w.push(ae)})).add(Ve.subscribe(()=>{w.forEach(ae=>{window.clearTimeout(ae)}),w=[]}))}return o});import{Subscription as hi}from"@vkontakte/videoplayer-core/evergreen";import{Observable as pi}from"@vkontakte/videoplayer-shared/evergreen";var mt=(r,e)=>new pi(i=>{let t=new hi,o=0;return t.add(r.info.position$.subscribe(()=>{let n=e.getTotalViewTime()*1e3;n>o&&n%e.targetDuration===0&&(o=n,i.next({target_duration:e.targetDuration,current_tvt:n}))})),t});import{Observable as gi,Subscription as fi,merge as vt}from"@vkontakte/videoplayer-shared/evergreen";var bt=r=>new gi(e=>{let i=new fi,t=0,o=1,n=0,l=!1,c=!1,s=()=>{if(!l)return;let f=Date.now();n+=(f-t)*o,t=f},a=()=>{(!l||c)&&(t=Date.now(),l=!0,c=!1)},u=()=>{l&&(s(),l=!1)},h=()=>{l&&(s(),l=!1,c=!0)},d=f=>{l&&s(),o=f,t=Date.now()},{started$:p,playing$:g,paused$:m,willSeek$:v,ended$:y,willDestruct$:T}=r.events,{currentPlaybackRate$:_}=r.info;i.add(v.subscribe(h)).add(vt(p,g).subscribe(a)).add(vt(m,y,T).subscribe(u)).add(_.subscribe(d));let P=()=>{let f=n;return l&&(f+=(Date.now()-t)*o),Math.floor(f/1e3)};return e.next(P),i});import{assertNever as It}from"@vkontakte/videoplayer-shared/evergreen";import{HttpConnectionType as xe,Surface as M,VideoFormat as b,VideoQuality as E}from"@vkontakte/videoplayer-core/evergreen";var ke=r=>r&&{[xe.HTTP1]:"http1",[xe.HTTP2]:"http2",[xe.QUIC]:"http3"}[r],Ce=r=>{if(r!==void 0)switch(r){case b.MPEG:return"MP4";case b.DASH:case b.DASH_LIVE:return"DASH";case b.DASH_SEP:return"DASH_SEP";case b.DASH_ONDEMAND:return"ONDEMAND_DASH";case b.HLS_ONDEMAND:return"ONDEMAND_HLS";case b.HLS:case b.HLS_LIVE:return"HLS";case b.HLS_FMP4:return"HLS_FMP4";case b.DASH_WEBM:case b.DASH_LIVE_WEBM:return"WEBM";case b.DASH_LIVE_CMAF:return"ONDEMAND_DASH_LIVE";case b.HLS_LIVE_CMAF:return"ONDEMAND_HLS_LIVE";case b.WEB_RTC_LIVE:return"WEBRTC";case b.DASH_WEBM_AV1:return"AV1";case b.DASH_STREAMS:return"MULTI_DASH";default:return It(r)}},C=r=>{if(r!==void 0)switch(r){case E.Q_144P:return"144p";case E.Q_240P:return"240p";case E.Q_360P:return"360p";case E.Q_480P:return"480p";case E.Q_720P:return"720p";case E.Q_1080P:return"1080p";case E.Q_1440P:return"1440p";case E.Q_2160P:return"2160p";case E.INVARIANT:case E.Q_576P:case E.Q_4320P:return"UNKNOWN";default:return It(r)}},yt=r=>{if(r!==void 0)switch(r){case"MP4":case"ONDEMAND_DASH":case"ONDEMAND_DASH_LIVE":case"ONDEMAND_HLS":case"ONDEMAND_HLS_LIVE":case"MULTI_DASH":case"WEBM":case"AV1":return"vod";case"DASH":case"HLS":case"HLS_FMP4":case"WEBRTC":return"live";default:return}},L=(r,e,i)=>{if(r&&e)switch(r){case b.MPEG:return i&&e[r]&&e[r][i];default:return e[r]?.url}},Le=(r,e=!1)=>{if(e)return"minimal";if(r!==void 0)switch(r){case M.NONE:return;case M.INLINE:return"inline";case M.FULLSCREEN:return"fullscreen";case M.SECOND_SCREEN:return"chromecast";case M.PIP:return"pip_external"}},re=r=>{if(r!==void 0)return r===M.INVISIBLE?"background":"foreground"};var St=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");var Ai="_thin-one-stat_",At=`${Ai}deviceId`,Et=()=>{let r=new De;return{subscription:r,subscribe:(e,i)=>{e&&r.add(e.subscribe(i))}}},se=class{constructor(e,i){this.debugLogger=new Ii;this.thinOneStatDebugLog=this.debugLogger.createComponentLog("ThinOneStat");this.eventNumber=1;this.playerSize={width:0,height:0};this.seekAction$=new Re("unknown");this.isid$=new Re(void 0);this.statContext=e,this.config=ct(i.config??{}),this.subscription=new De,this.config.synchronizeTime&&(this.timeSynchronisation=new oe);let t=new Pi,o=_t.get(At);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=Te(),_t.set(At,this.deviceId)),this.statContext.targetDuration?this.targetDuration=this.statContext.targetDuration:this.targetDuration=1e3,this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??St());let n=new ee({error$:t,config:this.config,timeSynchronisation:this.timeSynchronisation});this.api=new J({config:this.config,apiTransport:n,error$:t,deviceId:this.deviceId,refreshAuthToken:i.refreshAuthToken}),this.logger=new ie({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:l,topOrigin:c}=vi();this.isEmbed=l,this.embedHostname=c?new URL(c).hostname:void 0}get vsid$(){return new Re(k.getVSID())}authorize(e){return this.api.authorize(e)}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e,i){let t=new De,o=(s,a)=>t.add(s.subscribe(a));o(bt(e),s=>{this.getTotalViewTime=s}),o(e.info.isLive$,s=>this.isLive=s),o(e.info.position$,s=>this.position=s);let n;o(e.info.hostname$,s=>{n!==void 0&&n!==s&&this.logFailover({cdn_host:s});let u={cdn_host:s,connection_type:ke(e.info.httpConnectionType$.getValue()),connection_reused:e.info.httpConnectionReused$.getValue()};this.logCdnHostChanged(u),this.cdnHostname=n=s}),o(e.info.httpConnectionType$,s=>{this.connectionType=ke(s)}),o(e.info.httpConnectionReused$,s=>{this.connectionReused=s}),o(ft(e,i,{heartbeatInterval:this.config.watchCoverageHeartbeatInterval}),s=>{let a=Math.round(s.from*1e3),u=Math.round(s.to*1e3),h={watch_interval:`${a}-${u}`,in_history:!!this.statContext.inHistory,content_type:Ce(e.info.currentFormat$.getValue()),playback_quality:C(e.info.currentQuality$.getValue()),recom_info:this.statContext.recomInfo};if(!e.info.isLive$.getValue())this.logWatchCoverage(h);else{let p=e.info.atLiveEdge$.getValue();this.logWatchCoverageLive({...h,live:!!p})}}),o(mt(e,{targetDuration:this.targetDuration,getTotalViewTime:this.getTotalViewTime}),s=>{this.logWatchedN(s)}),o($e(e.events.willStart$,e.events.looped$),s=>{s&&this.resetViewSession();let a={isid:this.isid$.getValue(),stream_profile:yt(Ce(e.info.currentFormat$.getValue())),dpi:$.display.pixelRatio,web_layout:$.device.isMobile?"mobile":"desktop",preloaded:this.statContext.preload,navigation:this.statContext.navigation,recom_info:this.statContext.recomInfo};this.isEmbed&&(a.iframe_host=this.embedHostname??"unknown"),this.logStartSession(a)}),o(e.events.willReady$,()=>{if(this.statContext.preload){let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentBuffer$.getValue(),h=e.info.currentQuality$.getValue(),d={target_buffer_time:u?u.end-u.start:void 0,playback_url:L(s,a,h),playback_quality:C(h)};this.logPreloadStarted(d)}}),o(e.events.ready$,()=>{let s=e.info.currentBuffer$.getValue();if(this.statContext.preload){let a={buffer_time:s?s.end-s.start:void 0};this.logPreloadEnded(a)}this.logReady({buffer_time:s?s.end-s.start:void 0})}),o($e(e.events.fetcherRecoverableError$,e.events.fatalError$),()=>{this.statContext.preload&&this.logPreloadError()}),o(e.events.playing$,()=>{this.logPlay()}),o(e.events.manifestRequested$,()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused};this.logManifestRequest(h)}),o(e.events.firstBytesRequested$,()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused};this.logFirstMediaRequest(h)}),o(e.events.firstBytesReceived$,()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused};this.logFirstByteMedia(h)}),o(e.events.manifestReceived$,()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused};this.logManifestReceived(h)}),o(yi({connectionType:e.info.httpConnectionType$,connectionReused:e.info.httpConnectionReused$}).pipe(Si(({connectionReused:s})=>s!==void 0),_i((s,a)=>s.connectionType===a.connectionType)),()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused,rtt:e.info.rttEstimation$.getValue()};this.logConnectionEstablished(h)}),o(e.events.firstFrame$,()=>{this.logFirstVideoFrameDecoded()}),o(e.info.playbackState$,s=>{if(s===Pt.PLAYING){let a=e.info.currentBuffer$.getValue(),u={buffer_time:a?a.end-a.start:void 0};if(this.logPlaying(u),this.isStarted)this.logResume();else{this.isStarted=!0;let h=e.info.currentQuality$.getValue(),d=e.info.isAutoQualityEnabled$.getValue(),p=e.info.muted$.getValue(),g=e.info.volume$.getValue(),m=e.info.surface$.getValue(),v=e.info.availableTextTracks$.getValue(),y=e.info.currentTextTrack$.getValue(),T=e.info.currentAudioStream$.getValue(),_=e.info.currentPlaybackRate$.getValue(),P={playback_quality:C(h),user_quality:d?"auto":C(h),player_width:this.playerSize.width,player_height:this.playerSize.height,muted:p,sound_volume:g,buffer_time:a?Math.round(a.end-a.start):void 0,mode:Le(m,this.statContext.isPreviewPlayerView),visibility:re(m),subtitles_enabled:!!y,auto_subtitles:!!v.find(({id:f})=>f===y)?.isAuto,audio_track_lang:T?.language,playback_rate:_,recom_info:this.statContext.recomInfo};this.logPlaybackStarted(P)}}else s===Pt.PAUSED&&this.logPause()}),o(e.events.willSeek$,({to:s})=>{let a={target_position:s,seek_type:this.seekAction$.getValue()};this.logSeeking(a)}),o(e.events.seeked$,()=>{let a={target_position:e.info.position$.getValue(),seek_type:this.seekAction$.getValue()};this.logSeeked(a),this.seekAction$.next("unknown")}),o($e(e.info.isBuffering$,e.info.isStalled$),s=>{if(s){let a=e.info.currentBuffer$.getValue();this.logBufferStarvation({buffer_time:a?a.end-a.start:void 0}),this.logShowLoader()}}),o(e.info.currentQuality$,s=>{if(s){let a=e.info.isAutoQualityEnabled$.getValue(),u=e.info.currentVideoStream$.getValue()?.codec,h=e.info.currentAudioStream$.getValue()?.codec,d={user_quality:a?"auto":C(s),playback_quality:C(s),download_quality:C(s),codec_info:u&&h?`${u},${h}`:void 0,manual_switch:!a};this.logQualityChanged(d)}});let l,c;return o(e.info.surface$,s=>{this.logModeChanged({mode:Le(s,this.statContext.isPreviewPlayerView)}),c=re(s),l!==c&&(l=re(s),this.logVisibilityChanged({visibility:c}))}),o(e.events.stopped$,()=>{this.logStop()}),this.player=e,this.resubscribeBeforeunload(),this.subscription.add(t),t}attachToUi(e){let{subscribe:i,subscription:t}=Et();return i(e.actionSeek$,this.seekAction$),i(e.playerSize$,({width:o,height:n})=>{this.playerSize={width:o,height:n},this.logViewPortChanged({player_width:o,player_height:n})}),this.resubscribeBeforeunload(),this.subscription.add(t),t}attachToAds(e){let{subscription:i,subscribe:t}=Et();return t(e.init$,o=>{let n={slot:o};this.logAdvConfiguration(n)}),t(e.slotRequested$,()=>{this.logAdvRequest()}),t(e.started$,o=>{let n={adv_section:o};this.logAdvBreakStarted(n)}),t(e.ended$,o=>{let n={adv_section:o};this.logAdvBreakEnded(n)}),t(e.error$,o=>{let n={error_message:o};this.logAdvError(n)}),this.resubscribeBeforeunload(),this.subscription.add(i),i}getDeviceId(){return this.deviceId}resetViewSession(){this.thinOneStatDebugLog({message:"VSID reset"}),k.generateVSID(),this.eventNumber=0}destroy(){this.api.destroy()}createRequiredParams(e){let i=this.vsid$.getValue();mi(i);let t=this.eventNumber++;return{vsid:i,uv_movie_id:this.statContext.movieId,event_name:e,client_time:Date.now(),application:`@vkontakte/videoplayer-statistics:${S}`,platform:`web:${$.device.isMobile?"mobile":"desktop"}`,product:this.statContext.product,event_number:t,playback_position:this.isLive?void 0:Math.round(this.position),current_tvt:this.getTotalViewTime(),cdn_host:this.cdnHostname}}createRequiredFatParams(){return{stats_version:"2.1.1",browser:$.browser.current,browser_version:String($.browser.currentVersion),os:$.device.current,os_version:"",device_type:$.device.isMobile?"mobile":"desktop",navigation:this.statContext.navigation}}log(e,i,t=!1){let o=this.createRequiredParams(e),n={};t&&(n=this.createRequiredFatParams()),this.logger.log({...o,...n,...i})}logWatchCoverage(e){this.log("watch_coverage",e,!0)}logWatchCoverageLive(e){this.log("watch_coverage_live",e,!0)}logWatchedN(e){this.log("watched_n",e,!0)}logStartSession(e){this.log("start_session",e,!0)}logPreloadStarted(e){this.log("preload_started",e)}logPreloadEnded(e){this.log("preload_ended",e)}logPreloadError(){this.log("preload_error")}logPlaybackStarted(e){this.log("playback_started",e,!0)}logPlay(){this.log("play")}logManifestRequest(e){this.log("manifest_request",e)}logFirstMediaRequest(e){this.log("first_media_request",e)}logFirstByteMedia(e){this.log("first_byte_media",e)}logManifestReceived(e){this.log("manifest_received",e)}logConnectionEstablished(e){this.log("connection_established",e)}logFirstVideoFrameDecoded(){this.log("first_video_frame_decoded")}logReady(e){this.log("ready",e)}logPlaying(e){this.log("playing",e)}logPause(){this.log("pause")}logResume(){this.log("resume")}logSeeking(e){this.log("seeking",e)}logSeeked(e){this.log("seeked",e)}logStop(){this.log("stop")}logBufferStarvation(e){this.log("buffer_starvation",e)}logShowLoader(){this.log("show_loader")}logQualityChanged(e){this.log("quality_changed",e)}logCdnHostChanged(e){this.log("cdn_host_changed",e)}logViewPortChanged(e){this.log("view_port_changed",e)}logModeChanged(e){this.log("mode_changed",e)}logVisibilityChanged(e){this.log("visibility_changed",e)}logFailover(e){this.log("failover",e)}logAdvConfiguration(e){this.log("adv_configuration",e)}logAdvRequest(){this.log("adv_request")}logAdvBreakStarted(e){this.log("adv_break_started",e)}logAdvBreakEnded(e){this.log("adv_break_ended",e)}logAdvError(e){this.log("adv_error",e)}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=bi(window,"beforeunload").subscribe(()=>{}),this.subscription.add(this.beforeunloadSubscription)}};var Ei={};import{PlaybackState as xt,Subscription as Ti}from"@vkontakte/videoplayer-core/evergreen";import{Logger as wi}from"@vkontakte/videoplayer-shared/evergreen";var ne=class{constructor(){this.startTime=null;this.stopTime=null;this.accumulatedTime=0}get time(){return Math.floor(this.timeMs/1e3)}get timeMs(){return this.startTime===null?0:(this.stopTime??this.now())-this.startTime-this.accumulatedTime}get isRunning(){return this.startTime!==null&&this.stopTime===null}start(){this.isRunning||(this.stopTime!==null?(this.accumulatedTime+=this.now()-this.stopTime,this.stopTime=null):this.startTime=this.now())}stop(){this.isRunning&&(this.stopTime=this.now())}reset(){this.startTime=null,this.stopTime=null,this.accumulatedTime=0}now(){return Date.now()}};var wt=()=>window.Image?new Image:document.createElement("img");var Ne=class{constructor(e){this.position=0;this.started=!1;this.heartbeatPixels=[];this.heartbeatLastTimeSent={};this.idleCallbackIds=[];this.stopwatch=new ne;this.subscription=new Ti;this.params=e;let i=new wi;this.log=i.createComponentLog("MediascopePixel")}attachTo(e){this.subscription.add(e.info.playbackState$.subscribe(i=>this.onPlaybackState(i))).add(e.info.position$.subscribe(i=>this.onPosition(i))).add(e.info.atLiveEdge$.subscribe(i=>this.isActiveLive=i)),this.subscription.add(e.events.willSeek$.subscribe(()=>this.onWillSeek())).add(e.events.seeked$.subscribe(()=>this.onSeeked())).add(e.events.ended$.subscribe(()=>this.onEnded()))}destroy(){this.stopwatch.reset(),this.subscription.unsubscribe(),window.clearTimeout(this.heartbeatFirstTimeoutId),this.idleCallbackIds.forEach(e=>window.cancelIdleCallback(e)),this.send("stop")}onPlaybackState(e){e===xt.PLAYING?this.started?this.play():this.start():e===xt.PAUSED&&this.pause()}start(){this.started=!0,this.stopwatch.start(),this.send("start"),this.heartbeatPixels=this.prepareHeartbeatPixels(),this.heartbeatInterval=this.heartbeatPixels[0]?.interval;let e=this.heartbeatPixels[0]?.url,i=this.heartbeatPixels[0]?.delay;if(i!==void 0&&e)try{this.heartbeatFirstTimeoutId=window.setTimeout(()=>{this.sendHeartbeat(e)},i*1e3)}catch(t){this.log({message:t.message})}}play(){this.stopwatch.start(),this.send("resume")}pause(){this.stopwatch.stop(),this.send("pause")}onPosition(e){if(this.position=e,this.heartbeatInterval&&this.stopwatch.time!==0&&this.stopwatch.time%this.heartbeatInterval===0)for(let[i,{url:t}]of this.heartbeatPixels.entries())this.heartbeatLastTimeSent[i]!==this.stopwatch.time&&(this.heartbeatLastTimeSent[i]=this.stopwatch.time,this.sendHeartbeat(t))}onWillSeek(){this.started&&this.send("stop")}onSeeked(){this.started&&this.send("start")}onEnded(){this.stopwatch.stop(),this.send("stop")}validatePixels(e,i){return e?.filter(t=>t.event===i.event&&i.keys.every(o=>!!t[o]))}getFrameTimestamp(){let e;if(this.isActiveLive){let i=Math.floor(Math.random()*25)+5;e=Date.now()/1e3-i}else e=this.position||0;return Math.floor(e)}getUTC(){return Math.floor(Date.now()/1e3)}prepareUrl(e){let i=new URL(e);return i.pathname=i.pathname.replace("{@fts_fake_sec}",String(this.getFrameTimestamp())).replace("{@utc_sec}",String(this.getUTC())),i.search=[...new URLSearchParams(i.search)].filter(([t,o])=>!/={@[\w]+}/.test(`${t}=${o}`)).map(t=>t.join("=")).join("&"),i.toString()}preparePixels(e){return this.validatePixels(this.params.pixels,{event:e,keys:["url"]})}prepareHeartbeatPixels(){return this.validatePixels(this.params.pixels,{event:"heartbeat",keys:["url","interval"]})}call(e){try{this.idleCallbackIds.push(requestIdleCallback(()=>wt().src=this.prepareUrl(e)))}catch(i){this.log({message:i.message})}}send(e){let i=this.preparePixels(e);for(let{url:t}of i)this.call(t)}sendHeartbeat(e){this.call(e)}};export{F as ApiEnv,le as ConnectionType,ce as ContentType,Me as InteractiveInterfaceClick,Ne as MediascopePixel,Ei as MediascopePixelTypes,_e as OneStat,de as Quality,ue as SeekAction,Tt as ThinOneStat,S as VERSION};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vkontakte/videoplayer-statistics",
3
- "version": "1.0.83",
3
+ "version": "1.0.84-beta.0",
4
4
  "author": "vk.com",
5
5
  "description": "Statistics library for vk.com videoplayer",
6
6
  "homepage": "https://vk.com",
@@ -54,7 +54,7 @@
54
54
  "**/*.d.ts"
55
55
  ],
56
56
  "dependencies": {
57
- "@vkontakte/videoplayer-core": "2.0.137",
58
- "@vkontakte/videoplayer-shared": "1.0.65"
57
+ "@vkontakte/videoplayer-core": "2.0.138-beta.0",
58
+ "@vkontakte/videoplayer-shared": "1.0.66-beta.0"
59
59
  }
60
60
  }
@@ -0,0 +1,6 @@
1
+ export declare const generateVSID: () => string;
2
+ export declare class ShareVSID {
3
+ private static vsid;
4
+ static getVSID(): string;
5
+ static generateVSID(): string;
6
+ }
@@ -237,6 +237,10 @@ export interface IStatContext {
237
237
  refDomain?: string;
238
238
  inHistory?: boolean;
239
239
  deviceId?: string;
240
+ /**
241
+ * Плеер в режиме превью.
242
+ */
243
+ isPreviewPlayerView?: boolean;
240
244
  }
241
245
  export interface IConstructorParams {
242
246
  /** @deprecated Используете config.apiEnv */
@@ -270,7 +274,7 @@ export declare class OneStat implements IOneStat {
270
274
  experimental: {
271
275
  error$: IObservable<IError>;
272
276
  };
273
- vsid$: ValueSubject<string | undefined>;
277
+ get vsid$(): ValueSubject<string | undefined>;
274
278
  isid$: ValueSubject<string | undefined>;
275
279
  zenUid$: ValueSubject<string | undefined>;
276
280
  private statContext;
@@ -3,5 +3,5 @@ import { ConnectionType as StatisticsConnectionType, ContentType, Mode, Network,
3
3
  export declare const quality: (coreQuality: VideoQuality | undefined) => Quality | undefined;
4
4
  export declare const connectionType: (coreType: CoreConnectionType | undefined) => StatisticsConnectionType | undefined;
5
5
  export declare const contentType: (format: VideoFormat | undefined) => ContentType | undefined;
6
- export declare const surface: (surface: Surface | undefined) => Mode | undefined;
6
+ export declare const surface: (surface: Surface | undefined, isPreviewPlayerView?: boolean) => Mode | undefined;
7
7
  export declare const network: (effectiveType: "slow-2g" | "2g" | "3g" | "4g" | string) => Network | undefined;
@@ -26,6 +26,7 @@ export declare enum ContentType {
26
26
  DASH_SEP = "dash_sep",
27
27
  ONDEMAND_DASH = "ondemand_dash",
28
28
  HLS = "hls",
29
+ HLS_FMP4 = "hls_fmp4",
29
30
  ONDEMAND_HLS = "ondemand_hls",
30
31
  WEBM = "webm",
31
32
  AV1 = "av1",
@@ -61,7 +62,8 @@ export declare enum Mode {
61
62
  PREFETCH = "prefetch",
62
63
  AIRPLAY = "airplay",
63
64
  CHROMECAST = "chromecast",
64
- INVISIBLE = "invisible"
65
+ INVISIBLE = "invisible",
66
+ MINIMAL = "minimal"
65
67
  }
66
68
  export declare enum SeekAction {
67
69
  SLIDER = "slider",
@@ -2,8 +2,8 @@ import type { ISubscription, IValueObservable, Milliseconds, Seconds } from '@vk
2
2
  import { ValueSubject } from '@vkontakte/videoplayer-shared';
3
3
  import type { IPlayer } from '@vkontakte/videoplayer-core';
4
4
  import type { IOptionalConfig } from './config';
5
- import { Mode, Quality, SeekType, AutoQuality, Visibility } from './values';
6
- import type { IUIEvents } from './uiEvents';
5
+ import { Mode, Quality, SeekType, AutoQuality, Visibility, ConnectionType } from './values';
6
+ import type { IAdsEvents, IUIEvents } from './events';
7
7
  export interface IThinOneStat {
8
8
  vsid$: IValueObservable<string | undefined>;
9
9
  isid$: IValueObservable<string | undefined>;
@@ -21,8 +21,9 @@ export interface IThinOneStat {
21
21
  /**
22
22
  * Привязываемся к событиям и разным изменениям состояний плеера
23
23
  */
24
- attachTo(player: IPlayer): ISubscription;
24
+ attachTo(player: IPlayer, adsEvents: IAdsEvents): ISubscription;
25
25
  attachToUi(uiEvents: IUIEvents): ISubscription;
26
+ attachToAds(adsEvents: IAdsEvents): ISubscription;
26
27
  /**
27
28
  * Идентификатор текущего устройства
28
29
  */
@@ -36,10 +37,15 @@ export interface IStatContext {
36
37
  movieId?: number;
37
38
  deviceId?: string;
38
39
  preload?: boolean;
40
+ targetDuration?: Milliseconds;
39
41
  inHistory?: boolean;
40
42
  recomInfo?: Record<string, unknown>;
41
43
  product?: string;
42
44
  navigation?: Record<string, unknown>;
45
+ /**
46
+ * Плеер в режиме превью.
47
+ */
48
+ isPreviewPlayerView?: boolean;
43
49
  }
44
50
  export interface IConstructorParams {
45
51
  config: IOptionalConfig;
@@ -97,6 +103,40 @@ export interface IPlaybackStartedPayload {
97
103
  playback_rate?: number;
98
104
  recom_info?: Record<string, unknown>;
99
105
  }
106
+ export interface IManifestRequestPayload {
107
+ playback_url?: string;
108
+ cdn_host?: string;
109
+ connection_type?: ConnectionType;
110
+ connection_reused?: boolean;
111
+ }
112
+ export interface IFirstMediaRequestPayload {
113
+ playback_url?: string;
114
+ cdn_host?: string;
115
+ connection_type?: ConnectionType;
116
+ connection_reused?: boolean;
117
+ }
118
+ export interface IFirstByteMediaPayload {
119
+ playback_url?: string;
120
+ cdn_host?: string;
121
+ connection_type?: ConnectionType;
122
+ connection_reused?: boolean;
123
+ }
124
+ export interface IManifestReceivedPayload {
125
+ playback_url?: string;
126
+ cdn_host?: string;
127
+ connection_type?: ConnectionType;
128
+ connection_reused?: boolean;
129
+ }
130
+ export interface IConnectionEstablishedPayload {
131
+ playback_url?: string;
132
+ cdn_host?: string;
133
+ connection_type?: ConnectionType;
134
+ connection_reused?: boolean;
135
+ rtt?: Milliseconds;
136
+ }
137
+ export interface IReadyPayload {
138
+ buffer_time?: Milliseconds;
139
+ }
100
140
  export interface IPlayingPayload {
101
141
  buffer_time?: Milliseconds;
102
142
  }
@@ -108,6 +148,9 @@ export interface ISeekedPayload {
108
148
  target_position?: number;
109
149
  seek_type?: SeekType;
110
150
  }
151
+ export interface IBufferStarvationPayload {
152
+ buffer_time?: Milliseconds;
153
+ }
111
154
  export interface IQualityChangedPayload {
112
155
  user_quality?: Quality | AutoQuality;
113
156
  playback_quality?: Quality | AutoQuality;
@@ -115,9 +158,36 @@ export interface IQualityChangedPayload {
115
158
  codec_info?: string;
116
159
  manual_switch?: boolean;
117
160
  }
161
+ export interface ICdnHostChangedPayload {
162
+ cdn_host?: string;
163
+ connection_type?: ConnectionType;
164
+ connection_reused?: boolean;
165
+ }
166
+ export interface IViewPortChangedPayload {
167
+ player_width?: number;
168
+ player_height?: number;
169
+ }
170
+ export interface IModeChangedPayload {
171
+ mode?: Mode;
172
+ }
173
+ export interface IVisibilityChangedPayload {
174
+ visibility?: Visibility;
175
+ }
118
176
  export interface IFailoverPayload {
119
177
  cdn_host?: string;
120
178
  }
179
+ export interface IAdvConfigurationPayload {
180
+ slot?: number;
181
+ }
182
+ export interface IAdvBreakStartedPayload {
183
+ adv_section?: string;
184
+ }
185
+ export interface IAdvBreakEndedPayload {
186
+ adv_section?: string;
187
+ }
188
+ export interface IAdvErrorPayload {
189
+ error_message?: string;
190
+ }
121
191
  export declare class ThinOneStat implements IThinOneStat {
122
192
  private api;
123
193
  private logger;
@@ -127,6 +197,7 @@ export declare class ThinOneStat implements IThinOneStat {
127
197
  private timeSynchronisation?;
128
198
  private statContext;
129
199
  private deviceId;
200
+ private targetDuration;
130
201
  private debugLogger;
131
202
  private thinOneStatDebugLog;
132
203
  private eventNumber;
@@ -136,16 +207,20 @@ export declare class ThinOneStat implements IThinOneStat {
136
207
  private cdnHostname?;
137
208
  private isEmbed;
138
209
  private embedHostname?;
210
+ private connectionType?;
211
+ private connectionReused?;
212
+ private player;
213
+ private playerSize;
139
214
  private seekAction$;
140
- private playerSize$;
141
- vsid$: ValueSubject<string | undefined>;
215
+ get vsid$(): ValueSubject<string | undefined>;
142
216
  isid$: ValueSubject<string | undefined>;
143
217
  getTotalViewTime: () => Seconds;
144
218
  constructor(statContext: IStatContext, params: IConstructorParams);
145
219
  authorize(authToken?: string): Promise<unknown>;
146
220
  updateContext(newContext: Partial<IStatContext>): void;
147
- attachTo(player: IPlayer): ISubscription;
221
+ attachTo(player: IPlayer, adsEvents: IAdsEvents): ISubscription;
148
222
  attachToUi(events: IUIEvents): ISubscription;
223
+ attachToAds(events: IAdsEvents): ISubscription;
149
224
  getDeviceId(): string;
150
225
  resetViewSession(): void;
151
226
  destroy(): void;
@@ -158,15 +233,34 @@ export declare class ThinOneStat implements IThinOneStat {
158
233
  private logStartSession;
159
234
  private logPreloadStarted;
160
235
  private logPreloadEnded;
236
+ private logPreloadError;
161
237
  private logPlaybackStarted;
162
238
  private logPlay;
239
+ private logManifestRequest;
240
+ private logFirstMediaRequest;
241
+ private logFirstByteMedia;
242
+ private logManifestReceived;
243
+ private logConnectionEstablished;
244
+ private logFirstVideoFrameDecoded;
245
+ private logReady;
163
246
  private logPlaying;
164
247
  private logPause;
165
248
  private logResume;
166
249
  private logSeeking;
167
250
  private logSeeked;
251
+ private logStop;
252
+ private logBufferStarvation;
168
253
  private logShowLoader;
169
254
  private logQualityChanged;
255
+ private logCdnHostChanged;
256
+ private logViewPortChanged;
257
+ private logModeChanged;
258
+ private logVisibilityChanged;
170
259
  private logFailover;
260
+ private logAdvConfiguration;
261
+ private logAdvRequest;
262
+ private logAdvBreakStarted;
263
+ private logAdvBreakEnded;
264
+ private logAdvError;
171
265
  private resubscribeBeforeunload;
172
266
  }
@@ -7,3 +7,10 @@ export interface IUIEvents {
7
7
  height: number;
8
8
  }>;
9
9
  }
10
+ export interface IAdsEvents {
11
+ init$?: IObservable<number>;
12
+ slotRequested$?: IObservable<void>;
13
+ started$?: IObservable<string>;
14
+ ended$?: IObservable<string>;
15
+ error$?: IObservable<string>;
16
+ }
@@ -1,4 +1,4 @@
1
1
  export { IThinOneStat, ThinOneStat, IStatContext } from './ThinOneStat';
2
2
  export { SeekType } from './values';
3
- export { IUIEvents } from './uiEvents';
3
+ export { IUIEvents } from './events';
4
4
  export { VERSION } from '../env';
@@ -1,8 +1,9 @@
1
- import { ISources, Surface, VideoFormat, VideoQuality } from '@vkontakte/videoplayer-core';
2
- import { ContentType, Mode, Quality, StreamingProfile, Visibility } from '../values';
1
+ import { HttpConnectionType as CoreConnectionType, ISources, Surface, VideoFormat, VideoQuality } from '@vkontakte/videoplayer-core';
2
+ import { ConnectionType as StatisticsConnectionType, ContentType, Mode, Quality, StreamingProfile, Visibility } from '../values';
3
+ export declare const connectionType: (coreType?: CoreConnectionType) => StatisticsConnectionType | undefined;
3
4
  export declare const contentType: (format?: VideoFormat) => ContentType | undefined;
4
5
  export declare const quality: (coreQuality?: VideoQuality) => Quality | undefined;
5
6
  export declare const streamingProfile: (contentType?: ContentType) => StreamingProfile | undefined;
6
7
  export declare const formatUrl: (format?: VideoFormat, sources?: ISources, quality?: VideoQuality) => string | undefined;
7
- export declare const mode: (surface?: Surface) => Mode | undefined;
8
+ export declare const mode: (surface?: Surface, isPreviewPlayerView?: boolean) => Mode | undefined;
8
9
  export declare const visibility: (surface?: Surface) => Visibility | undefined;
@@ -1,6 +1,7 @@
1
1
  import { IPlayer } from '@vkontakte/videoplayer-core';
2
2
  import type { Seconds, IObservable, IRange } from '@vkontakte/videoplayer-shared';
3
+ import { IAdsEvents } from '../events';
3
4
  export type IParams = {
4
5
  heartbeatInterval?: Seconds;
5
6
  };
6
- export declare const watchCoverage: (player: IPlayer, params: IParams) => IObservable<IRange<Seconds>>;
7
+ export declare const watchCoverage: (player: IPlayer, adsEvents: IAdsEvents, params: IParams) => IObservable<IRange<Seconds>>;
@@ -1,7 +1,8 @@
1
1
  import type { IPlayer } from '@vkontakte/videoplayer-core';
2
- import type { IObservable, Seconds } from '@vkontakte/videoplayer-shared';
2
+ import type { IObservable, Milliseconds, Seconds } from '@vkontakte/videoplayer-shared';
3
3
  import { IWatchedNPayload } from '../ThinOneStat';
4
4
  export type IParams = {
5
+ targetDuration: Milliseconds;
5
6
  getTotalViewTime: () => Seconds;
6
7
  };
7
8
  export declare const watchedN: (player: IPlayer, params: IParams) => IObservable<IWatchedNPayload>;