@vkontakte/videoplayer-statistics 1.0.41-beta.2 → 1.0.41

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/esnext.cjs.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @vkontakte/videoplayer-statistics v1.0.41-beta.2
3
- * Tue, 10 Oct 2023 08:39:46 GMT
2
+ * @vkontakte/videoplayer-statistics v1.0.41
3
+ * Mon, 16 Oct 2023 13:03:33 GMT
4
4
  * https://st.mycdn.me/static/vkontakte-videoplayer/1-0-41/doc/
5
5
  */
6
- "use strict";var r=require("@vkontakte/videoplayer-shared/esnext.cjs.js"),R=require("lodash/debounce.js"),u=require("@vkontakte/videoplayer-core/esnext.cjs.js");exports.ApiEnv=void 0;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(exports.ApiEnv||(exports.ApiEnv={}));exports.Quality=void 0;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(exports.Quality||(exports.Quality={}));exports.ContentType=void 0;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.AV1="av1",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(exports.ContentType||(exports.ContentType={}));var w;(function(e){e.AUTO="auto",e.MANUAL=""})(w||(w={}));exports.ConnectionType=void 0;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})(exports.ConnectionType||(exports.ConnectionType={}));var g;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(g||(g={}));var E;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(E||(E={}));var S;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(S||(S={}));exports.SeekAction=void 0;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(exports.SeekAction||(exports.SeekAction={}));exports.InteractiveInterfaceClick=void 0;(function(e){e.GRAPH_SHOW="iGraphShow",e.GRAPH_HIDE="iGraphHide",e.NEXT_AREA="iNextChapterArea",e.NEXT_BUTTON="iNextChapterBtn",e.WATCH_AGAIN="iWatchAgainBtn"})(exports.InteractiveInterfaceClick||(exports.InteractiveInterfaceClick={}));const U={apiEnv:exports.ApiEnv.VK_ALIAS,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,disabledOperations:[],disabledCustomFields:[],useBeacon:!0,synchronizeTime:!0,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1}},H=e=>r.fillWithDefault(e,U);function M(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let s=0,i,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(s<=2&&(s=33554432+Math.random()*16777216|0),i=s&15,s=s>>4,t[o]=e[o===19?i&3|8:i]);return t.join("")}const O="1.0.41-beta.2",W="CIOPGQJGDIHBABABA",k={[exports.ApiEnv.PROD]:"https://api.ok.ru",[exports.ApiEnv.VK_ALIAS]:"https://api.mycdn.me",[exports.ApiEnv.VIDEOTEST]:"https://videotestapi.ok.ru/api",[exports.ApiEnv.TEST]:"https://apitest.ok.ru",[exports.ApiEnv.AUTO]:""},q="_one-stat_",P=`${q}uuid`;var b;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(b||(b={}));class Q{params;uuid;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new r.ValueSubject(!1);backoffTimeoutId;constructor(t){this.params=t;const s=r.safeStorage.get(P);s?s.startsWith('"')&&s.endsWith('"')?(this.uuid=s.replaceAll('"',""),r.safeStorage.set(P,this.uuid)):this.uuid=s:(this.uuid=M(),r.safeStorage.set(P,this.uuid))}async authorize(t){return this.authToken=t??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const s="log.externalLog",i=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(s,i,o)||this.logRequest(t)}async logRequest(t){const s="log.externalLog",i=this.createLogParams(t),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;const a=async(c,f=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(s,i,o)}catch(l){if(!l||!("error_code"in l)){this.params.error$.next({id:"logRequestUnknown",category:r.ErrorCategory.NETWORK,message:`Unknown ${s} error`,thrown:l});return}const d=l?.error_code;switch(d){case b.PARAM_SESSION_EXPIRED:case b.PARAM_SESSION_KEY:case b.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),f>0?a(c,f-1):void 0;case b.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),f>0?a(c,f-1):void 0;default:{this.params.error$.next({id:`LogRequest#${d}`,category:r.ErrorCategory.EXTERNAL_API,message:`${s} error`,data:l});return}}}};return a(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${O}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=r.getExponentialDelay(this.consequentAuthErrors,this.params.config.backoff);return new Promise(s=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(s).catch(i=>this.params.error$.next({id:"AuthorizeBackoff",category:r.ErrorCategory.NETWORK,message:"Otherwise unhandled error in authorization",thrown:i})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",s={session_data:{version:2,device_id:this.uuid,client_version:O.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(s.session_data.auth_token=this.authToken,s.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(t,s).then(i=>((!i||!i.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:r.ErrorCategory.EXTERNAL_API,message:"No session key",data:i}),this.sessionKey=i?.session_key??void 0,this.sessionKey)).catch(async i=>{this.sessionKey=void 0;const o=i?.error_code;switch(o){case b.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:r.ErrorCategory.EXTERNAL_API,message:"authorize error",data:i}):this.params.error$.next({id:"AuthorizeUnknown",category:r.ErrorCategory.NETWORK,message:"authorize error",thrown:i})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class ${constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(t,s,i){t in this.listeners||(this.listeners[t]=[]),this.listeners[t].push({callback:s,options:i})}removeEventListener(t,s){if(!(t in this.listeners))return;const i=this.listeners[t];for(let o=0,a=i.length;o<a;o++)if(i[o].callback===s){i.splice(o,1);return}}dispatchEvent(t){if(!(t.type in this.listeners))return;const i=this.listeners[t.type].slice();for(let o=0,a=i.length;o<a;o++){const c=i[o];try{c.callback.call(this,t)}catch(f){Promise.resolve().then(()=>{throw f})}c.options&&c.options.once&&this.removeEventListener(t.type,c.callback)}return!t.defaultPrevented}}class D extends ${constructor(){super(),this.listeners||$.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(t){t.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,t)),super.dispatchEvent(t)}}class K{constructor(){Object.defineProperty(this,"signal",{value:new D,writable:!0,configurable:!0})}abort(t){let s;try{s=new Event("abort")}catch{typeof document<"u"?document.createEvent?(s=document.createEvent("Event"),s.initEvent("abort",!1,!1)):(s=document.createEventObject(),s.type="abort"):s={type:"abort",bubbles:!1,cancelable:!1}}let i=t;if(i===void 0)if(typeof document>"u")i=new Error("This operation was aborted"),i.name="AbortError";else try{i=new DOMException("signal is aborted without reason")}catch{i=new Error("This operation was aborted"),i.name="AbortError"}this.signal.reason=i,this.signal.dispatchEvent(s)}toString(){return"[object AbortController]"}}typeof Symbol<"u"&&Symbol.toStringTag&&(K.prototype[Symbol.toStringTag]="AbortController",D.prototype[Symbol.toStringTag]="AbortSignal");function B(e){return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof e.Request=="function"&&!e.Request.prototype.hasOwnProperty("signal")||!e.AbortController}function z(e){typeof e=="function"&&(e={fetch:e});const{fetch:t,Request:s=t.Request,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=e;if(!B({fetch:t,Request:s,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:t,Request:a};let a=s;(a&&!a.prototype.hasOwnProperty("signal")||o)&&(a=function(d,n){let h;n&&n.signal&&(h=n.signal,delete n.signal);const p=new s(d,n);return h&&Object.defineProperty(p,"signal",{writable:!1,enumerable:!1,configurable:!0,value:h}),p},a.prototype=s.prototype);const c=t;return{fetch:(l,d)=>{const n=a&&a.prototype.isPrototypeOf(l)?l.signal:d?d.signal:void 0;if(n){let h;try{h=new DOMException("Aborted","AbortError")}catch{h=new Error("Aborted"),h.name="AbortError"}if(n.aborted)return Promise.reject(h);const p=new Promise((y,m)=>{n.addEventListener("abort",()=>m(h),{once:!0})});return d&&d.signal&&delete d.signal,Promise.race([p,c(l,d)])}return c(l,d)},Request:a}}const x=B({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),V=x?z({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,L=x?V.fetch:window.fetch;x?V.Request:window.Request;class j{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.config.apiEnv,this.apiBaseUrl=k[this.apiEnv],this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==exports.ApiEnv.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const t=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await L(t,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(t){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:r.ErrorCategory.NETWORK,message:"Unhandled resolve api base url error",thrown:t}),k[exports.ApiEnv.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,s,i){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:s,sessionKey:i}),a=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,a)}catch(c){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:r.ErrorCategory.NETWORK,message:"Unhandled beacon error",thrown:c,data:{method:t,params:s}})}return!1}async sendRequest(t,s,i){const o=r.now(),a=c=>{if(c instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(c.message)){this.params.error$.next({id:"Network",category:r.ErrorCategory.NETWORK,message:"Request failed",thrown:c});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:r.ErrorCategory.NETWORK,message:"Unhandled request error",thrown:c,data:{method:t,params:s,sessionKey:i,time:r.now()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),L(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:s,sessionKey:i})}).then(c=>{const f=Number(c.headers.get("content-length"))===0,l=new Date(c.headers.get("date")??"").getTime(),d=r.now()-o;if(isFinite(l)&&this.timeSynchronisation?.addServerTime(l,d),!f)return c.json().then(n=>Object.prototype.hasOwnProperty.call(n,"error_msg")?Promise.reject(n):n,a)},a)}_prepareQueryParams(t){const s=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&s.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([i,o])=>s.append(i,typeof o=="string"?o:JSON.stringify(o))),s}}const _="onestat_events",v=e=>t=>t.timestamp+e>=r.now();class G{params;api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;firstFlush;debouncedFlush;constructor(t){this.params=t,this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.firstFlush=R(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});const s=r.safeStorage.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=R(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:s}),this.subscription=this.api.authorized$.subscribe(i=>{i&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=t=>{const{operation:s,custom:{param:i}}=t;return["action_stop","close_at_empty_buffer"].includes(s)||s==="watch_coverage_record"&&i==="0-0"};safeFlush(){try{this.flush()}catch(t){this.error$.next({id:"LoggerError",category:r.ErrorCategory.WTF,message:String(t)??"Unknown logger error",thrown:t})}}readFromStorage(){const t=r.safeStorage.get(_);try{return t?JSON.parse(t):{}}catch{}return{}}addToStorage(t){if(!this.userSalt){this.unsaltedStorage.push(t);return}const s=this.readFromStorage(),o=(s[this.userSalt]??[]).filter(v(this.params.config.storageExpiration));r.safeStorage.set(_,JSON.stringify({...s,[this.userSalt]:[...o,t]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(v(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],r.safeStorage.set(_,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[s,i]of Object.entries(t)){const o=i.filter(v(this.params.config.storageExpiration));o.length?t[s]=o:delete t[s]}r.safeStorage.set(_,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const s=this.getFromStorage();s.length!==0&&(this.api.authorized$.getValue()?(t&&this.params.config.useBeacon?this.api.logBeacon(s):this.api.logRequest(s),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()}}const Y=()=>{let e,t;try{e=window.self!==window.top}catch(i){i instanceof DOMException&&i.name==="SecurityError"?e=!0:(e=!1,console.error(i))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(i){console.error(i)}try{!t&&document.referrer&&(t=document.referrer)}catch(i){console.error(i)}const s=t?new URL(t).hostname:void 0;return{isEmbed:e,host:s}},X=e=>e&&{[u.VideoQuality.INVARIANT]:exports.Quality.UNKNOWN,[u.VideoQuality.Q_144P]:exports.Quality.Q144P,[u.VideoQuality.Q_240P]:exports.Quality.Q240P,[u.VideoQuality.Q_360P]:exports.Quality.Q360P,[u.VideoQuality.Q_480P]:exports.Quality.Q480P,[u.VideoQuality.Q_720P]:exports.Quality.Q720P,[u.VideoQuality.Q_1080P]:exports.Quality.Q1080P,[u.VideoQuality.Q_1440P]:exports.Quality.Q1440P,[u.VideoQuality.Q_2160P]:exports.Quality.Q2160P,[u.VideoQuality.Q_4320P]:exports.Quality.UNKNOWN}[e],I=e=>e&&{[u.HttpConnectionType.HTTP1]:exports.ConnectionType.HTTP1,[u.HttpConnectionType.HTTP2]:exports.ConnectionType.HTTP2,[u.HttpConnectionType.QUIC]:exports.ConnectionType.HTTP3}[e],J=e=>{if(e!==void 0)switch(e){case u.VideoFormat.MPEG:return exports.ContentType.MP4;case u.VideoFormat.DASH:case u.VideoFormat.DASH_LIVE:return exports.ContentType.DASH;case u.VideoFormat.DASH_SEP:return exports.ContentType.DASH_SEP;case u.VideoFormat.DASH_ONDEMAND:return exports.ContentType.ONDEMAND_DASH;case u.VideoFormat.DASH_WEBM:case u.VideoFormat.DASH_LIVE_WEBM:return exports.ContentType.WEBM;case u.VideoFormat.DASH_WEBM_AV1:return exports.ContentType.AV1;case u.VideoFormat.DASH_LIVE_CMAF:return exports.ContentType.ONDEMAND_DASH_LIVE;case u.VideoFormat.HLS:case u.VideoFormat.HLS_LIVE:return exports.ContentType.HLS;case u.VideoFormat.HLS_ONDEMAND:return exports.ContentType.ONDEMAND_HLS;case u.VideoFormat.HLS_LIVE_CMAF:return exports.ContentType.ONDEMAND_HLS_LIVE;case u.VideoFormat.WEB_RTC_LIVE:return exports.ContentType.WEBRTC;default:return r.assertNever(e)}},C=e=>{if(e!==void 0)switch(e){case u.Surface.NONE:case u.Surface.INLINE:return;case u.Surface.FULLSCREEN:return S.FULLSCREEN;case u.Surface.SECOND_SCREEN:return S.EXTERNAL;case u.Surface.PIP:return S.PIP;default:return r.assertNever(e)}},Z=e=>{switch(e){case"slow-2g":return E.POOR;case"2g":return E.POOR;case"3g":return E.GOOD;case"4g":return E.EXCELLENT}};class tt{offset=void 0;constructor(t){this.offset=t}getOffset(){return this.offset??0}setOffset(t){this.offset=t}now(){return Date.now()+(this.offset??0)}date(t=new Date){return t.setTime(t.getTime()+(this.offset??0)),t}addServerTime(t,s){const i=Date.now(),o=t-i-s/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)}}const F=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),et=e=>new r.Observable(t=>{const s=new r.Subscription,i=r.merge(r.fromEvent(window,"beforeunload"),e.events.willDestruct$),o=new r.ValueSubject(void 0);let a;s.add(e.info.isLive$.pipe(r.filterChanged()).subscribe(A=>{a&&(a.unsubscribe(),o.next(void 0)),A?a=e.info.liveTime$.pipe(r.map(T=>T&&T/1e3)).subscribe(o):a=e.info.position$.subscribe(o),s.add(a)}));const{playing$:c,paused$:f}=e.events,l=e.events.willSeek$.pipe(r.filter(()=>e.info.playbackState$.getValue()===u.PlaybackState.PLAYING)),d=e.events.seeked$.pipe(r.filter(()=>e.info.playbackState$.getValue()===u.PlaybackState.PLAYING));let n=!1;const h=new r.Subject;s.add(l.subscribe(()=>{n||h.next(),n=!0})),s.add(d.subscribe(()=>n=!1));const p=r.merge(c,d),y=r.merge(f,h,i,e.events.looped$);let m;return s.add(p.subscribe(()=>m=o.getValue())),s.add(y.subscribe(()=>{const A=o.getValue();r.isNullable(m)||m===A||r.isNullable(A)||(t.next({from:m,to:A}),m=void 0)})),s}),N=()=>{const e=new r.Subscription;return{subscription:e,subscribe:(t,s)=>{t&&e.add(t.subscribe(s))}}};class it{api;logger;config;subscription=new r.Subscription;beforeunloadSubscription;timeSynchronisation;experimental;statContext;vsid=F();isEmbed;embedParent;uiEvents;player;seekAction$=new r.ValueSubject(exports.SeekAction.UNKNOWN);constructor(t,s){this.statContext=t,this.config=H(s.config??{}),r.isNonNullable(s.apiEnv)&&(this.config.apiEnv=s.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new tt);const i=new r.Subject;this.experimental={error$:i};const o=new j({apiKey:W,config:this.config,error$:i,timeSynchronisation:this.timeSynchronisation});this.api=new Q({config:this.config,apiTransport:o,refreshAuthToken:s.refreshAuthToken,mobile:this.statContext.mobile??!1,error$:i}),this.logger=new G({config:this.config,api:this.api,error$:i,userSalt:s.userSalt});const{isEmbed:a,host:c}=Y();this.isEmbed=a,this.embedParent=c,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const s=new r.Subscription,i=(n,h)=>s.add(n.subscribe(h));i(t.events.willStart$,()=>{const n=t.info.position$.getValue();this.logActionPlay({position:n}),this.statContext.projectId&&this.logActionPlayWithProjectId({position:n})}),i(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(exports.SeekAction.UNKNOWN)}),i(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),i(t.events.willResume$,()=>{this.logPlay()}),i(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),i(et(t),n=>{const h=t.info.isLive$.getValue(),p={start:parseFloat(n.from.toFixed(3)),end:parseFloat(n.to.toFixed(3))};h?this.logWatchCoverageLive(p):this.logWatchCoverageRecord(p)});let o;i(t.info.isStalled$,n=>{n?o=r.now():(r.isNonNullable(o)&&this.logEmptyBuffer({duration:r.now()-o}),o=void 0)});let a=!1;s.add(t.events.fatalError$.pipe(r.once()).subscribe(()=>a=!0)),i(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const h=r.isNonNullable(o)?r.now()-o:void 0;this.logCloseAtEmptyBuffer({duration:h??0}),o=void 0}else a||this.logActionStop()}),i(t.events.managedError$,({id:n})=>{this.logError({fatal:!1,errorType:n})}),i(t.events.fatalError$,({id:n})=>{this.logError({fatal:!0,errorType:n})});let c,f,l=!1;i(t.events.firstBytes$,n=>{c=r.now(),this.logFirstBytes({time:n})}),i(t.events.willStart$,()=>f=r.now()),i(t.info.currentBuffer$,n=>{!l&&n&&n.end-n.start>0&&r.isNonNullable(c)&&(this.logPlayerReady({duration:r.now()-c}),l=!0)}),i(t.events.firstFrame$,()=>{r.isNonNullable(c)&&!l&&(this.logPlayerReady({duration:r.now()-c}),l=!0),r.isNonNullable(f)&&this.logFirstFrame({time:r.now()-f})}),i(t.info.atLiveEdge$,n=>this.updateContext({liveEdge:n})),i(r.combine({muted:t.info.muted$,volume:t.info.volume$}),({muted:n,volume:h})=>this.updateContext({audible:!n&&h>0})),i(t.info.currentQuality$,n=>this.updateContext({quality:X(n)})),i(t.info.isAutoQualityEnabled$,n=>this.updateContext({autoQuality:n})),i(t.info.currentFormat$,n=>this.updateContext({contentType:J(n)}));let d;return i(t.info.hostname$,n=>{this.updateContext({cdnHostname:n,failover:d!==void 0&&d!==n}),d=n}),i(t.info.throughputEstimation$,n=>this.updateContext({downloadSpeed:n})),i(t.info.httpConnectionType$,n=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:I(n)}),this.updateContext({connectionType:I(n)})}),i(t.info.httpConnectionReused$,n=>{r.isNullable(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:n}),this.updateContext({connectionReused:n})}),i(t.info.surface$,n=>this.updateContext({mode:C(n)})),i(r.combine({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:n,available:h})=>{const p=h.find(({id:y})=>y===n);this.updateContext({subtitles:p?.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(s),s}attachToUi(t){this.uiEvents=t;const{subscription:s,subscribe:i}=N();return this.player&&(i(t.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),i(t.actionSeek$,this.seekAction$),i(t.inPiP$,o=>{const a=o?S.PIP:C(this.player?.info.surface$.getValue());this.updateContext({mode:a})}),i(t.inFullscreen$,o=>{const a=o?S.FULLSCREEN:C(this.player?.info.surface$.getValue());this.updateContext({mode:a})}),i(t.actionSetSubtitle$,o=>this.updateContext({subtitles:o})),i(t.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(s)),s}attachToAds(t){const{subscription:s,subscribe:i}=N();return i(t.slotRequested$,()=>this.logAdSlotRequest()),i(t.started$,o=>this.logAdStarted(o)),i(t.paused$,()=>this.logAdPaused()),i(t.resumed$,()=>this.logAdResumed()),i(t.ended$,()=>this.logAdEnded()),i(t.skipped$,()=>this.logAdSkipped()),i(t.clicked$,()=>this.logAdClicked()),this.resubscribeBeforeunload(),this.subscription.add(s),s}attachToInteractive(t){const{subscription:s,subscribe:i}=N();return i(t.click$,o=>this.logInterfaceClick(o)),i(t.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(s),s}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=F()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const s=this.timeSynchronisation?.getOffset()??0,i=t.start+s,o=t.end+s;this.log({operation:"watch_coverage_live",param:`${i}-${o}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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(t){this.log({operation:"player_interface_click",param:t})}logNextMovie(t){this.log({operation:"next_movie",param:String(t)})}subscribe(){this.resubscribeBeforeunload();const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(r.merge(r.fromEvent(t,"change"),r.observableFrom(["init"])).subscribe(()=>this.updateContext({network:Z(t.effectiveType)})))}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=r.fromEvent(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logActionPlayWithProjectId(t){if(!this.statContext.projectId)return;const s=this.createLogItem({operation:"action_play",param:String(Math.round(t.position))});s.custom.vid=this.statContext.projectId,this.logger.log(s)}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){if(this.config.disabledOperations.includes(t.operation))return;const s=this.createLogItem(t);this.logger.log(s)}createLogItem({operation:t,param:s,time:i}){const o=this.timeSynchronisation?.now()??r.now(),a=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,c=this.statContext.firstConnectionReused,f={vsid:this.vsid,vid:this.statContext.movieId,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?w.AUTO:this.statContext.autoplay===!1?w.MANUAL:void 0,param:s,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:a,connection_reused:c===!0?g.YES:c===!1?g.NO:void 0,cached_data:this.statContext.cached===!0?g.YES:this.statContext.cached===!1?g.NO:void 0,live:this.statContext.liveEdge?g.YES:void 0,muted:this.statContext.audible===!1?g.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:g.YES,ref_domain:this.isEmbed?this.embedParent:this.statContext.refUrl,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};for(const l of this.config.disabledCustomFields)delete f[l];return{operation:t,type:1,time:i,network:this.statContext.network,timestamp:o,custom:f}}}exports.OneStat=it;exports.VERSION=O;
6
+ "use strict";var r=require("@vkontakte/videoplayer-shared/esnext.cjs.js"),k=require("lodash/debounce.js"),u=require("@vkontakte/videoplayer-core/esnext.cjs.js");exports.ApiEnv=void 0;(function(t){t.PROD="prod",t.VK_ALIAS="vk_alias",t.VIDEOTEST="videotest",t.TEST="test",t.AUTO="auto"})(exports.ApiEnv||(exports.ApiEnv={}));exports.Quality=void 0;(function(t){t.Q144P="mobile",t.Q240P="lowest",t.Q360P="low",t.Q480P="medium",t.Q720P="high",t.Q1080P="fullhd",t.Q1440P="quadhd",t.Q2160P="ultrahd",t.UNKNOWN="unknown"})(exports.Quality||(exports.Quality={}));exports.ContentType=void 0;(function(t){t.MP4="mp4",t.DASH="dash",t.DASH_SEP="dash_sep",t.ONDEMAND_DASH="ondemand_dash",t.HLS="hls",t.ONDEMAND_HLS="ondemand_hls",t.WEBM="webm",t.AV1="av1",t.ONDEMAND_DASH_LIVE="ondemand_dash_live",t.ONDEMAND_HLS_LIVE="ondemand_hls_live",t.WEBRTC="webrtc",t.UNKNOWN="unknown",t.RTMP="rtmp"})(exports.ContentType||(exports.ContentType={}));var v;(function(t){t.AUTO="auto",t.MANUAL=""})(v||(v={}));exports.ConnectionType=void 0;(function(t){t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3"})(exports.ConnectionType||(exports.ConnectionType={}));var p;(function(t){t[t.YES=1]="YES",t[t.NO=0]="NO"})(p||(p={}));var y;(function(t){t.EXCELLENT="excellent",t.GOOD="good",t.POOR="poor"})(y||(y={}));var E;(function(t){t.PIP="pip",t.FULLSCREEN="fullscreen",t.EXTERNAL="external",t.PREFETCH="prefetch",t.AIRPLAY="airplay",t.CHROMECAST="chromecast",t.INVISIBLE="invisible"})(E||(E={}));exports.SeekAction=void 0;(function(t){t.SLIDER="slider",t.DOUBLE_TAP="double_tap",t.TIME_CODE="time_code",t.EPISODE="episode",t.REWIND="rewind",t.LIVE="live",t.UNKNOWN="unknown"})(exports.SeekAction||(exports.SeekAction={}));exports.InteractiveInterfaceClick=void 0;(function(t){t.GRAPH_SHOW="iGraphShow",t.GRAPH_HIDE="iGraphHide",t.NEXT_AREA="iNextChapterArea",t.NEXT_BUTTON="iNextChapterBtn",t.WATCH_AGAIN="iWatchAgainBtn"})(exports.InteractiveInterfaceClick||(exports.InteractiveInterfaceClick={}));const M={action_play:"ap",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"},W={vsid:"si",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"},Q={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},K={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv"},j={apiEnv:exports.ApiEnv.VK_ALIAS,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageInterval:15e3,disabledOperations:[],disabledCustomFields:[],shorten:!0,embedUrlParams:[],useBeacon:!0,synchronizeTime:!0,debugLog:!1,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1}},z=t=>r.fillWithDefault(t,j);function G(){const t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36);let s=0,i,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(s<=2&&(s=33554432+Math.random()*16777216|0),i=s&15,s=s>>4,e[o]=t[o===19?i&3|8:i]);return e.join("")}const Y=t=>{const{operation:e,custom:s}=t,i=Object.fromEntries(Object.entries(s).map(([o,a])=>{const c=W[o]??o;let f=a;return a&&(o==="mode"?f=K[a]??a:o==="quality"&&(f=Q[a]??a)),[c,f]}));return{...t,operation:M[e]??e,custom:i}},O="1.0.41",X="CIOPGQJGDIHBABABA",I={[exports.ApiEnv.PROD]:"https://api.ok.ru",[exports.ApiEnv.VK_ALIAS]:"https://api.mycdn.me",[exports.ApiEnv.VIDEOTEST]:"https://videotestapi.ok.ru/api",[exports.ApiEnv.TEST]:"https://apitest.ok.ru",[exports.ApiEnv.AUTO]:""};var S;(function(t){t[t.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",t[t.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",t[t.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",t[t.AUTH_LOGIN=401]="AUTH_LOGIN"})(S||(S={}));class J{params;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new r.ValueSubject(!1);backoffTimeoutId;constructor(e){this.params=e}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(e){const s="log.externalLog",i=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(s,i,o)||this.logRequest(e)}async logRequest(e){const s="log.externalLog",i=this.createLogParams(e),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;const a=async(c,f=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(s,i,o)}catch(h){if(!h||!("error_code"in h)){this.params.error$.next({id:"logRequestUnknown",category:r.ErrorCategory.NETWORK,message:`Unknown ${s} error`,thrown:h});return}const d=h?.error_code;switch(d){case S.PARAM_SESSION_EXPIRED:case S.PARAM_SESSION_KEY:case S.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),f>0?a(c,f-1):void 0;case S.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),f>0?a(c,f-1):void 0;default:{this.params.error$.next({id:`LogRequest#${d}`,category:r.ErrorCategory.EXTERNAL_API,message:`${s} error`,data:h});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",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${O}`,platform:this.params.mobile?"M_WEB":"WEB",items:this.params.config.shorten?e.map(Y):e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const e=r.getExponentialDelay(this.consequentAuthErrors,this.params.config.backoff);return new Promise(s=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(s).catch(i=>this.params.error$.next({id:"AuthorizeBackoff",category:r.ErrorCategory.NETWORK,message:"Otherwise unhandled error in authorization",thrown:i})).finally(()=>this.backoffTimeoutId=0)},e))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const e="auth.anonymLogin",s={session_data:{version:2,device_id:this.params.uuid,client_version:O.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(s.session_data.auth_token=this.authToken,s.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,s).then(i=>((!i||!i.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:r.ErrorCategory.EXTERNAL_API,message:"No session key",data:i}),this.sessionKey=i?.session_key??void 0,this.sessionKey)).catch(async i=>{this.sessionKey=void 0;const o=i?.error_code;switch(o){case S.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:r.ErrorCategory.EXTERNAL_API,message:"authorize error",data:i}):this.params.error$.next({id:"AuthorizeUnknown",category:r.ErrorCategory.NETWORK,message:"authorize error",thrown:i})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class D{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(e,s,i){e in this.listeners||(this.listeners[e]=[]),this.listeners[e].push({callback:s,options:i})}removeEventListener(e,s){if(!(e in this.listeners))return;const i=this.listeners[e];for(let o=0,a=i.length;o<a;o++)if(i[o].callback===s){i.splice(o,1);return}}dispatchEvent(e){if(!(e.type in this.listeners))return;const i=this.listeners[e.type].slice();for(let o=0,a=i.length;o<a;o++){const c=i[o];try{c.callback.call(this,e)}catch(f){Promise.resolve().then(()=>{throw f})}c.options&&c.options.once&&this.removeEventListener(e.type,c.callback)}return!e.defaultPrevented}}class B extends D{constructor(){super(),this.listeners||D.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(e){e.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,e)),super.dispatchEvent(e)}}class Z{constructor(){Object.defineProperty(this,"signal",{value:new B,writable:!0,configurable:!0})}abort(e){let s;try{s=new Event("abort")}catch{typeof document<"u"?document.createEvent?(s=document.createEvent("Event"),s.initEvent("abort",!1,!1)):(s=document.createEventObject(),s.type="abort"):s={type:"abort",bubbles:!1,cancelable:!1}}let i=e;if(i===void 0)if(typeof document>"u")i=new Error("This operation was aborted"),i.name="AbortError";else try{i=new DOMException("signal is aborted without reason")}catch{i=new Error("This operation was aborted"),i.name="AbortError"}this.signal.reason=i,this.signal.dispatchEvent(s)}toString(){return"[object AbortController]"}}typeof Symbol<"u"&&Symbol.toStringTag&&(Z.prototype[Symbol.toStringTag]="AbortController",B.prototype[Symbol.toStringTag]="AbortSignal");function U(t){return t.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof t.Request=="function"&&!t.Request.prototype.hasOwnProperty("signal")||!t.AbortController}function ee(t){typeof t=="function"&&(t={fetch:t});const{fetch:e,Request:s=e.Request,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=t;if(!U({fetch:e,Request:s,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:e,Request:a};let a=s;(a&&!a.prototype.hasOwnProperty("signal")||o)&&(a=function(d,n){let l;n&&n.signal&&(l=n.signal,delete n.signal);const g=new s(d,n);return l&&Object.defineProperty(g,"signal",{writable:!1,enumerable:!1,configurable:!0,value:l}),g},a.prototype=s.prototype);const c=e;return{fetch:(h,d)=>{const n=a&&a.prototype.isPrototypeOf(h)?h.signal:d?d.signal:void 0;if(n){let l;try{l=new DOMException("Aborted","AbortError")}catch{l=new Error("Aborted"),l.name="AbortError"}if(n.aborted)return Promise.reject(l);const g=new Promise((m,_)=>{n.addEventListener("abort",()=>_(l),{once:!0})});return d&&d.signal&&delete d.signal,Promise.race([g,c(h,d)])}return c(h,d)},Request:a}}const L=U({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),q=L?ee({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,F=L?q.fetch:window.fetch;L?q.Request:window.Request;class te{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(e){this.params=e,this.apiKey=e.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=I[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==exports.ApiEnv.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await F(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:r.ErrorCategory.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),I[exports.ApiEnv.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(e,s,i){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:e,queryParams:s,sessionKey:i}),a=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,a)}catch(c){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:r.ErrorCategory.NETWORK,message:"Unhandled beacon error",thrown:c,data:{method:e,params:s}})}return!1}async sendRequest(e,s,i){const o=r.now(),a=c=>{if(c instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(c.message)){this.params.error$.next({id:"Network",category:r.ErrorCategory.NETWORK,message:"Request failed",thrown:c});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:r.ErrorCategory.NETWORK,message:"Unhandled request error",thrown:c,data:{method:e,params:s,sessionKey:i,time:r.now()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),F(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:s,sessionKey:i})}).then(c=>{const f=Number(c.headers.get("content-length"))===0,h=new Date(c.headers.get("date")??"").getTime(),d=r.now()-o;if(isFinite(h)&&this.timeSynchronisation?.addServerTime(h,d),!f)return c.json().then(n=>Object.prototype.hasOwnProperty.call(n,"error_msg")?Promise.reject(n):n,a)},a)}_prepareQueryParams(e){const s=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&s.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([i,o])=>s.append(i,typeof o=="string"?o:JSON.stringify(o))),s}}const w="onestat_events",P=t=>e=>e.timestamp+t>=r.now();class ie{params;api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;firstFlush;debouncedFlush;loggerDebugLog;constructor(e){this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=k(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});const s=r.safeStorage.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=k(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:s}),this.subscription=this.api.authorized$.subscribe(i=>{i&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=e=>{const{operation:s,custom:{param:i}}=e;return["action_stop","close_at_empty_buffer"].includes(s)||s==="watch_coverage_record"&&i==="0-0"};safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:r.ErrorCategory.WTF,message:String(e)??"Unknown logger error",thrown:e})}}readFromStorage(){const e=r.safeStorage.get(w);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}const s=this.readFromStorage(),o=(s[this.userSalt]??[]).filter(P(this.params.config.storageExpiration));r.safeStorage.set(w,JSON.stringify({...s,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(P(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const e=this.readFromStorage();delete e[this.userSalt],r.safeStorage.set(w,JSON.stringify(e))}housekeepStorage(){const e=this.readFromStorage();for(const[s,i]of Object.entries(e)){const o=i.filter(P(this.params.config.storageExpiration));o.length?e[s]=o:delete e[s],this.loggerDebugLog({message:`${i.length} retrieved from storage, ${o.length} of them actual`})}r.safeStorage.set(w,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(e=!1){const s=this.getFromStorage();s.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${s.length} events through beacon`}),this.api.logBeacon(s)):(this.loggerDebugLog({message:`Flushing ${s.length} events`}),this.api.logRequest(s)),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()}}const se=()=>{let t,e;try{t=window.self!==window.top}catch(i){i instanceof DOMException&&i.name==="SecurityError"?t=!0:(t=!1,console.error(i))}try{window.location.ancestorOrigins&&(e=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(i){console.error(i)}try{!e&&document.referrer&&(e=document.referrer)}catch(i){console.error(i)}const s=e?new URL(e).hostname:void 0;return{isEmbed:t,host:s}},oe=t=>t&&{[u.VideoQuality.INVARIANT]:exports.Quality.UNKNOWN,[u.VideoQuality.Q_144P]:exports.Quality.Q144P,[u.VideoQuality.Q_240P]:exports.Quality.Q240P,[u.VideoQuality.Q_360P]:exports.Quality.Q360P,[u.VideoQuality.Q_480P]:exports.Quality.Q480P,[u.VideoQuality.Q_720P]:exports.Quality.Q720P,[u.VideoQuality.Q_1080P]:exports.Quality.Q1080P,[u.VideoQuality.Q_1440P]:exports.Quality.Q1440P,[u.VideoQuality.Q_2160P]:exports.Quality.Q2160P,[u.VideoQuality.Q_4320P]:exports.Quality.UNKNOWN}[t],V=t=>t&&{[u.HttpConnectionType.HTTP1]:exports.ConnectionType.HTTP1,[u.HttpConnectionType.HTTP2]:exports.ConnectionType.HTTP2,[u.HttpConnectionType.QUIC]:exports.ConnectionType.HTTP3}[t],re=t=>{if(t!==void 0)switch(t){case u.VideoFormat.MPEG:return exports.ContentType.MP4;case u.VideoFormat.DASH:case u.VideoFormat.DASH_LIVE:return exports.ContentType.DASH;case u.VideoFormat.DASH_SEP:return exports.ContentType.DASH_SEP;case u.VideoFormat.DASH_ONDEMAND:return exports.ContentType.ONDEMAND_DASH;case u.VideoFormat.DASH_WEBM:case u.VideoFormat.DASH_LIVE_WEBM:return exports.ContentType.WEBM;case u.VideoFormat.DASH_WEBM_AV1:return exports.ContentType.AV1;case u.VideoFormat.DASH_LIVE_CMAF:return exports.ContentType.ONDEMAND_DASH_LIVE;case u.VideoFormat.HLS:case u.VideoFormat.HLS_LIVE:return exports.ContentType.HLS;case u.VideoFormat.HLS_ONDEMAND:return exports.ContentType.ONDEMAND_HLS;case u.VideoFormat.HLS_LIVE_CMAF:return exports.ContentType.ONDEMAND_HLS_LIVE;case u.VideoFormat.WEB_RTC_LIVE:return exports.ContentType.WEBRTC;default:return r.assertNever(t)}},C=t=>{if(t!==void 0)switch(t){case u.Surface.NONE:case u.Surface.INLINE:return;case u.Surface.FULLSCREEN:return E.FULLSCREEN;case u.Surface.SECOND_SCREEN:return E.CHROMECAST;case u.Surface.PIP:return E.PIP;default:return r.assertNever(t)}},ne=t=>{switch(t){case"slow-2g":return y.POOR;case"2g":return y.POOR;case"3g":return y.GOOD;case"4g":return y.EXCELLENT}};class ae{offset=void 0;constructor(e){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,s){const i=Date.now(),o=e-i-s/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)}}const ce=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),ue=(t,e)=>new r.Observable(s=>{const i=new r.Subscription,o=r.merge(r.fromEvent(window,"beforeunload"),t.events.willDestruct$),a=new r.ValueSubject(void 0);let c;i.add(t.info.isLive$.pipe(r.filterChanged()).subscribe(b=>{c&&(c.unsubscribe(),a.next(void 0)),b?c=t.info.liveTime$.pipe(r.map(T=>T&&T/1e3)).subscribe(a):c=t.info.position$.subscribe(a),i.add(c)}));const{playing$:f,paused$:h}=t.events,d=t.events.willSeek$.pipe(r.filter(()=>t.info.playbackState$.getValue()===u.PlaybackState.PLAYING)),n=t.events.seeked$.pipe(r.filter(()=>t.info.playbackState$.getValue()===u.PlaybackState.PLAYING));let l=!1;const g=new r.Subject;i.add(d.subscribe(()=>{l||g.next(),l=!0})),i.add(n.subscribe(()=>l=!1));const m=r.merge(f,n),_=r.merge(h,g,o,t.events.looped$);let A;const $=()=>A=a.getValue(),R=()=>{const b=a.getValue();r.isNullable(A)||A===b||r.isNullable(b)||(s.next({from:A,to:b}),A=void 0)},H=()=>{R(),$()};if(i.add(m.subscribe($)),i.add(_.subscribe(R)),e.forceInterval&&isFinite(e.forceInterval)){let b=0;i.add(m.subscribe(()=>b=window.setTimeout(H,e.forceInterval))),i.add(_.subscribe(()=>window.clearTimeout(b)))}return i}),le="_one-stat_",N=`${le}uuid`,x=()=>{const t=new r.Subscription;return{subscription:t,subscribe:(e,s)=>{e&&t.add(e.subscribe(s))}}};class he{api;logger;config;subscription=new r.Subscription;beforeunloadSubscription;timeSynchronisation;debugLogger=new r.Logger;oneStatDebugLog=this.debugLogger.createComponentLog("onestat");experimental;vsid$=new r.ValueSubject(void 0);statContext;isEmbed;embedParent;uiEvents;player;seekAction$=new r.ValueSubject(exports.SeekAction.UNKNOWN);uuid;constructor(e,s){this.statContext=e,this.config=z(s.config??{}),r.isNonNullable(s.apiEnv)&&(this.config.apiEnv=s.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new ae);const i=new r.Subject;this.experimental={error$:i};const o=r.safeStorage.get(N);o?o.startsWith('"')&&o.endsWith('"')?(this.uuid=o.replaceAll('"',""),r.safeStorage.set(N,this.uuid)):this.uuid=o:(this.uuid=G(),r.safeStorage.set(N,this.uuid)),this.resetViewSession();const a=new te({apiKey:X,config:this.config,error$:i,timeSynchronisation:this.timeSynchronisation});this.api=new J({config:this.config,apiTransport:a,refreshAuthToken:s.refreshAuthToken,mobile:this.statContext.mobile??!1,uuid:this.uuid,error$:i}),this.logger=new ie({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:i,userSalt:s.userSalt});const{isEmbed:c,host:f}=se();this.isEmbed=c,this.embedParent=f,this.subscribe()}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){const s=new r.Subscription,i=(n,l)=>s.add(n.subscribe(l));i(e.events.willStart$,()=>{const n=e.info.position$.getValue();this.logActionPlay({position:n}),this.statContext.projectId&&this.logActionPlayWithProjectId({position:n})}),i(e.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:e.info.position$.getValue()})}),i(e.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:e.info.position$.getValue()}),this.seekAction$.next(exports.SeekAction.UNKNOWN)}),i(e.events.paused$,()=>{this.logPause({position:e.info.position$.getValue()})}),i(e.events.willResume$,()=>{this.logPlay()}),i(e.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),i(ue(e,{forceInterval:this.config.watchCoverageInterval}),n=>{const l=e.info.isLive$.getValue(),g={start:parseFloat(n.from.toFixed(3)),end:parseFloat(n.to.toFixed(3))};l?this.logWatchCoverageLive(g):this.logWatchCoverageRecord(g)});let o;i(e.info.isStalled$,n=>{n?o=r.now():(r.isNonNullable(o)&&this.logEmptyBuffer({duration:r.now()-o}),o=void 0)});let a=!1;s.add(e.events.fatalError$.pipe(r.once()).subscribe(()=>a=!0)),i(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){const l=r.isNonNullable(o)?r.now()-o:void 0;this.logCloseAtEmptyBuffer({duration:l??0}),o=void 0}else a||this.logActionStop()}),i(e.events.managedError$,({id:n})=>{this.logError({fatal:!1,errorType:n})}),i(e.events.fatalError$,({id:n})=>{this.logError({fatal:!0,errorType:n})});let c,f,h=!1;i(e.events.firstBytes$,n=>{c=r.now(),this.logFirstBytes({time:n})}),i(e.events.willStart$,()=>f=r.now()),i(e.info.currentBuffer$,n=>{!h&&n&&n.end-n.start>0&&r.isNonNullable(c)&&(this.logPlayerReady({duration:r.now()-c}),h=!0)}),i(e.events.firstFrame$,()=>{r.isNonNullable(c)&&!h&&(this.logPlayerReady({duration:r.now()-c}),h=!0),r.isNonNullable(f)&&this.logFirstFrame({time:r.now()-f})}),i(e.info.atLiveEdge$,n=>this.updateContext({liveEdge:n})),i(r.combine({muted:e.info.muted$,volume:e.info.volume$}),({muted:n,volume:l})=>this.updateContext({audible:!n&&l>0})),i(e.info.currentQuality$,n=>this.updateContext({quality:oe(n)})),i(e.info.isAutoQualityEnabled$,n=>this.updateContext({autoQuality:n})),i(e.info.currentFormat$,n=>this.updateContext({contentType:re(n)})),i(e.info.currentPlaybackRate$,n=>this.updateContext({rate:n})),i(e.info.is3DVideo$,n=>this.updateContext({is3d:n}));let d;return i(e.info.hostname$,n=>{this.updateContext({cdnHostname:n,failover:d!==void 0&&d!==n}),d=n}),i(e.info.throughputEstimation$,n=>this.updateContext({downloadSpeed:n})),i(e.info.httpConnectionType$,n=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:V(n)}),this.updateContext({connectionType:V(n)})}),i(e.info.httpConnectionReused$,n=>{r.isNullable(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:n}),this.updateContext({connectionReused:n})}),i(e.info.surface$,n=>this.updateContext({mode:C(n)})),i(r.combine({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:n,available:l})=>{const g=l.find(({id:m})=>m===n);this.updateContext({subtitles:g?.language})}),this.player=e,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(s),s}attachToUi(e){this.uiEvents=e;const{subscription:s,subscribe:i}=x();return this.player&&(i(e.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),i(e.actionSeek$,this.seekAction$),i(e.inPiP$,o=>{const a=o?E.PIP:C(this.player?.info.surface$.getValue());this.updateContext({mode:a})}),i(e.inFullscreen$,o=>{const a=o?E.FULLSCREEN:C(this.player?.info.surface$.getValue());this.updateContext({mode:a})}),i(e.actionSetSubtitle$,o=>this.updateContext({subtitles:o})),i(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(s)),s}attachToAds(e){const{subscription:s,subscribe:i}=x();return i(e.slotRequested$,()=>this.logAdSlotRequest()),i(e.started$,o=>this.logAdStarted(o)),i(e.paused$,()=>this.logAdPaused()),i(e.resumed$,()=>this.logAdResumed()),i(e.ended$,()=>this.logAdEnded()),i(e.skipped$,()=>this.logAdSkipped()),i(e.clicked$,()=>this.logAdClicked()),this.resubscribeBeforeunload(),this.subscription.add(s),s}attachToInteractive(e){const{subscription:s,subscribe:i}=x();return i(e.click$,o=>this.logInterfaceClick(o)),i(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(s),s}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(ce())}getDeviceId(){return this.uuid}setFieldBlacklist(){}logInited(){}logReady(e){this.log({operation:"player_ready",param:String(e.time)})}logStarted(...e){this.logActionPlay(...e)}logPlay(){this.log({operation:"play_toggle"})}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}`})}logWatchCoverageLive(e){const s=this.timeSynchronisation?.getOffset()??0,i=e.start+s,o=e.end+s;this.log({operation:"watch_coverage_live",param:`${i}-${o}`})}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();const e=window.navigator.connection;e&&"onchange"in e&&"effectiveType"in e&&this.subscription.add(r.merge(r.fromEvent(e,"change"),r.observableFrom(["init"])).subscribe(()=>this.updateContext({network:ne(e.effectiveType)}))),this.config.debugLog&&this.debugLogger.log$.subscribe(s=>{console.debug("%c stat ","background:#fa6470;",`component: ${s.component}.`,s.message)})}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=r.fromEvent(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),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))})}logActionPlayWithProjectId(e){this.statContext.projectId&&this.log({operation:"action_play",param:String(Math.round(e.position))},{vid:this.statContext.projectId})}logCloseAtEmptyBuffer(e){this.log({operation:"close_at_empty_buffer",param:String(Math.round(e.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(e,s={}){if(this.config.disabledOperations.includes(e.operation))return;this.oneStatDebugLog({message:`operation ${e.operation} ${e.param}`});const i=this.createLogItem(e,s);this.logger.log(i)}createLogItem({operation:e,param:s,time:i},o={}){const a=this.timeSynchronisation?.now()??r.now(),c=this.vsid$.getValue();r.assertNonNullable(c);const f=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,h=this.statContext.firstConnectionReused;let d,n;if(this.isEmbed){d=this.embedParent;const g=[...new URLSearchParams(location.search).entries()].filter(([m,_])=>this.config.embedUrlParams.includes(m));n=new URLSearchParams(g).toString()}else this.statContext.place==="direct"&&(document.referrer&&(d=new URL(document.referrer).hostname),n=location.href.substring(0,1024));const l={vsid:c,vid:this.statContext.movieId,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?v.AUTO:this.statContext.autoplay===!1?v.MANUAL:void 0,param:s,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:f,connection_reused:h===!0?p.YES:h===!1?p.NO:void 0,cached_data:this.statContext.cached===!0?p.YES:this.statContext.cached===!1?p.NO:void 0,live:this.statContext.liveEdge?p.YES:void 0,muted:this.statContext.audible===!1?p.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:p.YES,ref_domain:d,direct_url:n,rate:this.statContext.rate===1||r.isNullable(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(const g of this.config.disabledCustomFields)delete l[g];return{operation:e,type:1,time:i,network:this.statContext.network,timestamp:a,custom:l}}}exports.OneStat=he;exports.VERSION=O;
package/esnext.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @vkontakte/videoplayer-statistics v1.0.41-beta.2
3
- * Tue, 10 Oct 2023 08:39:46 GMT
2
+ * @vkontakte/videoplayer-statistics v1.0.41
3
+ * Mon, 16 Oct 2023 13:03:33 GMT
4
4
  * https://st.mycdn.me/static/vkontakte-videoplayer/1-0-41/doc/
5
5
  */
6
- import{fillWithDefault as ct,ValueSubject as V,safeStorage as _,getExponentialDelay as ut,ErrorCategory as b,now as p,assertNever as it,Observable as ht,Subscription as C,merge as k,fromEvent as H,filterChanged as lt,map as dt,filter as z,Subject as ot,isNullable as q,isNonNullable as T,once as ft,combine as Q,observableFrom as pt}from"@vkontakte/videoplayer-shared/esnext.esm.js";import j from"lodash/debounce.js";import{Surface as x,VideoQuality as S,HttpConnectionType as B,VideoFormat as d,PlaybackState as G}from"@vkontakte/videoplayer-core/esnext.esm.js";var E;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(E||(E={}));var g;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(g||(g={}));var f;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.AV1="av1",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(f||(f={}));var L;(function(e){e.AUTO="auto",e.MANUAL=""})(L||(L={}));var R;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})(R||(R={}));var A;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(A||(A={}));var v;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(v||(v={}));var P;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(P||(P={}));var I;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(I||(I={}));var Y;(function(e){e.GRAPH_SHOW="iGraphShow",e.GRAPH_HIDE="iGraphHide",e.NEXT_AREA="iNextChapterArea",e.NEXT_BUTTON="iNextChapterBtn",e.WATCH_AGAIN="iWatchAgainBtn"})(Y||(Y={}));const gt={apiEnv:E.VK_ALIAS,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,disabledOperations:[],disabledCustomFields:[],useBeacon:!0,synchronizeTime:!0,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1}},mt=e=>ct(e,gt);function bt(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let i=0,s,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),s=i&15,i=i>>4,t[o]=e[o===19?s&3|8:s]);return t.join("")}const X="1.0.41-beta.2",St="CIOPGQJGDIHBABABA",J={[E.PROD]:"https://api.ok.ru",[E.VK_ALIAS]:"https://api.mycdn.me",[E.VIDEOTEST]:"https://videotestapi.ok.ru/api",[E.TEST]:"https://apitest.ok.ru",[E.AUTO]:""},Et="_one-stat_",F=`${Et}uuid`;var y;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(y||(y={}));class At{params;uuid;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new V(!1);backoffTimeoutId;constructor(t){this.params=t;const i=_.get(F);i?i.startsWith('"')&&i.endsWith('"')?(this.uuid=i.replaceAll('"',""),_.set(F,this.uuid)):this.uuid=i:(this.uuid=bt(),_.set(F,this.uuid))}async authorize(t){return this.authToken=t??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const i="log.externalLog",s=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,s,o)||this.logRequest(t)}async logRequest(t){const i="log.externalLog",s=this.createLogParams(t),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;const n=async(a,l=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,s,o)}catch(c){if(!c||!("error_code"in c)){this.params.error$.next({id:"logRequestUnknown",category:b.NETWORK,message:`Unknown ${i} error`,thrown:c});return}const h=c?.error_code;switch(h){case y.PARAM_SESSION_EXPIRED:case y.PARAM_SESSION_KEY:case y.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),l>0?n(a,l-1):void 0;case y.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),l>0?n(a,l-1):void 0;default:{this.params.error$.next({id:`LogRequest#${h}`,category:b.EXTERNAL_API,message:`${i} error`,data:c});return}}}};return n(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${X}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=ut(this.consequentAuthErrors,this.params.config.backoff);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(s=>this.params.error$.next({id:"AuthorizeBackoff",category:b.NETWORK,message:"Otherwise unhandled error in authorization",thrown:s})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",i={session_data:{version:2,device_id:this.uuid,client_version:X.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(t,i).then(s=>((!s||!s.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:b.EXTERNAL_API,message:"No session key",data:s}),this.sessionKey=s?.session_key??void 0,this.sessionKey)).catch(async s=>{this.sessionKey=void 0;const o=s?.error_code;switch(o){case y.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:b.EXTERNAL_API,message:"authorize error",data:s}):this.params.error$.next({id:"AuthorizeUnknown",category:b.NETWORK,message:"authorize error",thrown:s})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class Z{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(t,i,s){t in this.listeners||(this.listeners[t]=[]),this.listeners[t].push({callback:i,options:s})}removeEventListener(t,i){if(!(t in this.listeners))return;const s=this.listeners[t];for(let o=0,n=s.length;o<n;o++)if(s[o].callback===i){s.splice(o,1);return}}dispatchEvent(t){if(!(t.type in this.listeners))return;const s=this.listeners[t.type].slice();for(let o=0,n=s.length;o<n;o++){const a=s[o];try{a.callback.call(this,t)}catch(l){Promise.resolve().then(()=>{throw l})}a.options&&a.options.once&&this.removeEventListener(t.type,a.callback)}return!t.defaultPrevented}}class rt extends Z{constructor(){super(),this.listeners||Z.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(t){t.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,t)),super.dispatchEvent(t)}}class _t{constructor(){Object.defineProperty(this,"signal",{value:new rt,writable:!0,configurable:!0})}abort(t){let i;try{i=new Event("abort")}catch{typeof document<"u"?document.createEvent?(i=document.createEvent("Event"),i.initEvent("abort",!1,!1)):(i=document.createEventObject(),i.type="abort"):i={type:"abort",bubbles:!1,cancelable:!1}}let s=t;if(s===void 0)if(typeof document>"u")s=new Error("This operation was aborted"),s.name="AbortError";else try{s=new DOMException("signal is aborted without reason")}catch{s=new Error("This operation was aborted"),s.name="AbortError"}this.signal.reason=s,this.signal.dispatchEvent(i)}toString(){return"[object AbortController]"}}typeof Symbol<"u"&&Symbol.toStringTag&&(_t.prototype[Symbol.toStringTag]="AbortController",rt.prototype[Symbol.toStringTag]="AbortSignal");function nt(e){return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof e.Request=="function"&&!e.Request.prototype.hasOwnProperty("signal")||!e.AbortController}function wt(e){typeof e=="function"&&(e={fetch:e});const{fetch:t,Request:i=t.Request,AbortController:s,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=e;if(!nt({fetch:t,Request:i,AbortController:s,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:t,Request:n};let n=i;(n&&!n.prototype.hasOwnProperty("signal")||o)&&(n=function(h,r){let u;r&&r.signal&&(u=r.signal,delete r.signal);const m=new i(h,r);return u&&Object.defineProperty(m,"signal",{writable:!1,enumerable:!1,configurable:!0,value:u}),m},n.prototype=i.prototype);const a=t;return{fetch:(c,h)=>{const r=n&&n.prototype.isPrototypeOf(c)?c.signal:h?h.signal:void 0;if(r){let u;try{u=new DOMException("Aborted","AbortError")}catch{u=new Error("Aborted"),u.name="AbortError"}if(r.aborted)return Promise.reject(u);const m=new Promise((N,w)=>{r.addEventListener("abort",()=>w(u),{once:!0})});return h&&h.signal&&delete h.signal,Promise.race([m,a(c,h)])}return a(c,h)},Request:n}}const K=nt({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),at=K?wt({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,tt=K?at.fetch:window.fetch;K?at.Request:window.Request;class yt{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.config.apiEnv,this.apiBaseUrl=J[this.apiEnv],this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==E.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const t=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await tt(t,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(t){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:b.NETWORK,message:"Unhandled resolve api base url error",thrown:t}),J[E.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,i,s){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:i,sessionKey:s}),n=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,n)}catch(a){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:b.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:t,params:i}})}return!1}async sendRequest(t,i,s){const o=p(),n=a=>{if(a instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(a.message)){this.params.error$.next({id:"Network",category:b.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:b.NETWORK,message:"Unhandled request error",thrown:a,data:{method:t,params:i,sessionKey:s,time:p()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),tt(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:i,sessionKey:s})}).then(a=>{const l=Number(a.headers.get("content-length"))===0,c=new Date(a.headers.get("date")??"").getTime(),h=p()-o;if(isFinite(c)&&this.timeSynchronisation?.addServerTime(c,h),!l)return a.json().then(r=>Object.prototype.hasOwnProperty.call(r,"error_msg")?Promise.reject(r):r,n)},n)}_prepareQueryParams(t){const i=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&i.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([s,o])=>i.append(s,typeof o=="string"?o:JSON.stringify(o))),i}}const $="onestat_events",U=e=>t=>t.timestamp+e>=p();class Pt{params;api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;firstFlush;debouncedFlush;constructor(t){this.params=t,this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.firstFlush=j(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});const i=_.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=j(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=t=>{const{operation:i,custom:{param:s}}=t;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&s==="0-0"};safeFlush(){try{this.flush()}catch(t){this.error$.next({id:"LoggerError",category:b.WTF,message:String(t)??"Unknown logger error",thrown:t})}}readFromStorage(){const t=_.get($);try{return t?JSON.parse(t):{}}catch{}return{}}addToStorage(t){if(!this.userSalt){this.unsaltedStorage.push(t);return}const i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(U(this.params.config.storageExpiration));_.set($,JSON.stringify({...i,[this.userSalt]:[...o,t]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(U(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],_.set($,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[i,s]of Object.entries(t)){const o=s.filter(U(this.params.config.storageExpiration));o.length?t[i]=o:delete t[i]}_.set($,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const i=this.getFromStorage();i.length!==0&&(this.api.authorized$.getValue()?(t&&this.params.config.useBeacon?this.api.logBeacon(i):this.api.logRequest(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()}}const Tt=()=>{let e,t;try{e=window.self!==window.top}catch(s){s instanceof DOMException&&s.name==="SecurityError"?e=!0:(e=!1,console.error(s))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(s){console.error(s)}try{!t&&document.referrer&&(t=document.referrer)}catch(s){console.error(s)}const i=t?new URL(t).hostname:void 0;return{isEmbed:e,host:i}},vt=e=>e&&{[S.INVARIANT]:g.UNKNOWN,[S.Q_144P]:g.Q144P,[S.Q_240P]:g.Q240P,[S.Q_360P]:g.Q360P,[S.Q_480P]:g.Q480P,[S.Q_720P]:g.Q720P,[S.Q_1080P]:g.Q1080P,[S.Q_1440P]:g.Q1440P,[S.Q_2160P]:g.Q2160P,[S.Q_4320P]:g.UNKNOWN}[e],et=e=>e&&{[B.HTTP1]:R.HTTP1,[B.HTTP2]:R.HTTP2,[B.QUIC]:R.HTTP3}[e],Nt=e=>{if(e!==void 0)switch(e){case d.MPEG:return f.MP4;case d.DASH:case d.DASH_LIVE:return f.DASH;case d.DASH_SEP:return f.DASH_SEP;case d.DASH_ONDEMAND:return f.ONDEMAND_DASH;case d.DASH_WEBM:case d.DASH_LIVE_WEBM:return f.WEBM;case d.DASH_WEBM_AV1:return f.AV1;case d.DASH_LIVE_CMAF:return f.ONDEMAND_DASH_LIVE;case d.HLS:case d.HLS_LIVE:return f.HLS;case d.HLS_ONDEMAND:return f.ONDEMAND_HLS;case d.HLS_LIVE_CMAF:return f.ONDEMAND_HLS_LIVE;case d.WEB_RTC_LIVE:return f.WEBRTC;default:return it(e)}},M=e=>{if(e!==void 0)switch(e){case x.NONE:case x.INLINE:return;case x.FULLSCREEN:return P.FULLSCREEN;case x.SECOND_SCREEN:return P.EXTERNAL;case x.PIP:return P.PIP;default:return it(e)}},Ot=e=>{switch(e){case"slow-2g":return v.POOR;case"2g":return v.POOR;case"3g":return v.GOOD;case"4g":return v.EXCELLENT}};class xt{offset=void 0;constructor(t){this.offset=t}getOffset(){return this.offset??0}setOffset(t){this.offset=t}now(){return Date.now()+(this.offset??0)}date(t=new Date){return t.setTime(t.getTime()+(this.offset??0)),t}addServerTime(t,i){const s=Date.now(),o=t-s-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)}}const st=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),Rt=e=>new ht(t=>{const i=new C,s=k(H(window,"beforeunload"),e.events.willDestruct$),o=new V(void 0);let n;i.add(e.info.isLive$.pipe(lt()).subscribe(O=>{n&&(n.unsubscribe(),o.next(void 0)),O?n=e.info.liveTime$.pipe(dt(D=>D&&D/1e3)).subscribe(o):n=e.info.position$.subscribe(o),i.add(n)}));const{playing$:a,paused$:l}=e.events,c=e.events.willSeek$.pipe(z(()=>e.info.playbackState$.getValue()===G.PLAYING)),h=e.events.seeked$.pipe(z(()=>e.info.playbackState$.getValue()===G.PLAYING));let r=!1;const u=new ot;i.add(c.subscribe(()=>{r||u.next(),r=!0})),i.add(h.subscribe(()=>r=!1));const m=k(a,h),N=k(l,u,s,e.events.looped$);let w;return i.add(m.subscribe(()=>w=o.getValue())),i.add(N.subscribe(()=>{const O=o.getValue();q(w)||w===O||q(O)||(t.next({from:w,to:O}),w=void 0)})),i}),W=()=>{const e=new C;return{subscription:e,subscribe:(t,i)=>{t&&e.add(t.subscribe(i))}}};class Lt{api;logger;config;subscription=new C;beforeunloadSubscription;timeSynchronisation;experimental;statContext;vsid=st();isEmbed;embedParent;uiEvents;player;seekAction$=new V(I.UNKNOWN);constructor(t,i){this.statContext=t,this.config=mt(i.config??{}),T(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new xt);const s=new ot;this.experimental={error$:s};const o=new yt({apiKey:St,config:this.config,error$:s,timeSynchronisation:this.timeSynchronisation});this.api=new At({config:this.config,apiTransport:o,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,error$:s}),this.logger=new Pt({config:this.config,api:this.api,error$:s,userSalt:i.userSalt});const{isEmbed:n,host:a}=Tt();this.isEmbed=n,this.embedParent=a,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const i=new C,s=(r,u)=>i.add(r.subscribe(u));s(t.events.willStart$,()=>{const r=t.info.position$.getValue();this.logActionPlay({position:r}),this.statContext.projectId&&this.logActionPlayWithProjectId({position:r})}),s(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),s(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(I.UNKNOWN)}),s(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),s(t.events.willResume$,()=>{this.logPlay()}),s(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),s(Rt(t),r=>{const u=t.info.isLive$.getValue(),m={start:parseFloat(r.from.toFixed(3)),end:parseFloat(r.to.toFixed(3))};u?this.logWatchCoverageLive(m):this.logWatchCoverageRecord(m)});let o;s(t.info.isStalled$,r=>{r?o=p():(T(o)&&this.logEmptyBuffer({duration:p()-o}),o=void 0)});let n=!1;i.add(t.events.fatalError$.pipe(ft()).subscribe(()=>n=!0)),s(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const u=T(o)?p()-o:void 0;this.logCloseAtEmptyBuffer({duration:u??0}),o=void 0}else n||this.logActionStop()}),s(t.events.managedError$,({id:r})=>{this.logError({fatal:!1,errorType:r})}),s(t.events.fatalError$,({id:r})=>{this.logError({fatal:!0,errorType:r})});let a,l,c=!1;s(t.events.firstBytes$,r=>{a=p(),this.logFirstBytes({time:r})}),s(t.events.willStart$,()=>l=p()),s(t.info.currentBuffer$,r=>{!c&&r&&r.end-r.start>0&&T(a)&&(this.logPlayerReady({duration:p()-a}),c=!0)}),s(t.events.firstFrame$,()=>{T(a)&&!c&&(this.logPlayerReady({duration:p()-a}),c=!0),T(l)&&this.logFirstFrame({time:p()-l})}),s(t.info.atLiveEdge$,r=>this.updateContext({liveEdge:r})),s(Q({muted:t.info.muted$,volume:t.info.volume$}),({muted:r,volume:u})=>this.updateContext({audible:!r&&u>0})),s(t.info.currentQuality$,r=>this.updateContext({quality:vt(r)})),s(t.info.isAutoQualityEnabled$,r=>this.updateContext({autoQuality:r})),s(t.info.currentFormat$,r=>this.updateContext({contentType:Nt(r)}));let h;return s(t.info.hostname$,r=>{this.updateContext({cdnHostname:r,failover:h!==void 0&&h!==r}),h=r}),s(t.info.throughputEstimation$,r=>this.updateContext({downloadSpeed:r})),s(t.info.httpConnectionType$,r=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:et(r)}),this.updateContext({connectionType:et(r)})}),s(t.info.httpConnectionReused$,r=>{q(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:r}),this.updateContext({connectionReused:r})}),s(t.info.surface$,r=>this.updateContext({mode:M(r)})),s(Q({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:r,available:u})=>{const m=u.find(({id:N})=>N===r);this.updateContext({subtitles:m?.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(t){this.uiEvents=t;const{subscription:i,subscribe:s}=W();return this.player&&(s(t.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),s(t.actionSeek$,this.seekAction$),s(t.inPiP$,o=>{const n=o?P.PIP:M(this.player?.info.surface$.getValue());this.updateContext({mode:n})}),s(t.inFullscreen$,o=>{const n=o?P.FULLSCREEN:M(this.player?.info.surface$.getValue());this.updateContext({mode:n})}),s(t.actionSetSubtitle$,o=>this.updateContext({subtitles:o})),s(t.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i)),i}attachToAds(t){const{subscription:i,subscribe:s}=W();return s(t.slotRequested$,()=>this.logAdSlotRequest()),s(t.started$,o=>this.logAdStarted(o)),s(t.paused$,()=>this.logAdPaused()),s(t.resumed$,()=>this.logAdResumed()),s(t.ended$,()=>this.logAdEnded()),s(t.skipped$,()=>this.logAdSkipped()),s(t.clicked$,()=>this.logAdClicked()),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToInteractive(t){const{subscription:i,subscribe:s}=W();return s(t.click$,o=>this.logInterfaceClick(o)),s(t.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i),i}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=st()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const i=this.timeSynchronisation?.getOffset()??0,s=t.start+i,o=t.end+i;this.log({operation:"watch_coverage_live",param:`${s}-${o}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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(t){this.log({operation:"player_interface_click",param:t})}logNextMovie(t){this.log({operation:"next_movie",param:String(t)})}subscribe(){this.resubscribeBeforeunload();const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(k(H(t,"change"),pt(["init"])).subscribe(()=>this.updateContext({network:Ot(t.effectiveType)})))}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=H(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logActionPlayWithProjectId(t){if(!this.statContext.projectId)return;const i=this.createLogItem({operation:"action_play",param:String(Math.round(t.position))});i.custom.vid=this.statContext.projectId,this.logger.log(i)}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){if(this.config.disabledOperations.includes(t.operation))return;const i=this.createLogItem(t);this.logger.log(i)}createLogItem({operation:t,param:i,time:s}){const o=this.timeSynchronisation?.now()??p(),n=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,a=this.statContext.firstConnectionReused,l={vsid:this.vsid,vid:this.statContext.movieId,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?L.AUTO:this.statContext.autoplay===!1?L.MANUAL:void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:n,connection_reused:a===!0?A.YES:a===!1?A.NO:void 0,cached_data:this.statContext.cached===!0?A.YES:this.statContext.cached===!1?A.NO:void 0,live:this.statContext.liveEdge?A.YES:void 0,muted:this.statContext.audible===!1?A.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:A.YES,ref_domain:this.isEmbed?this.embedParent:this.statContext.refUrl,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};for(const c of this.config.disabledCustomFields)delete l[c];return{operation:t,type:1,time:s,network:this.statContext.network,timestamp:o,custom:l}}}export{E as ApiEnv,R as ConnectionType,f as ContentType,Y as InteractiveInterfaceClick,Lt as OneStat,g as Quality,I as SeekAction,X as VERSION};
6
+ import{fillWithDefault as le,ValueSubject as k,getExponentialDelay as de,ErrorCategory as b,now as p,safeStorage as y,assertNever as re,Observable as fe,Subscription as I,merge as R,fromEvent as K,filterChanged as ge,map as pe,filter as G,Subject as ne,isNullable as D,Logger as me,isNonNullable as T,once as be,combine as Y,observableFrom as Se,assertNonNullable as _e}from"@vkontakte/videoplayer-shared/esnext.esm.js";import X from"lodash/debounce.js";import{Surface as N,VideoQuality as S,HttpConnectionType as q,VideoFormat as f,PlaybackState as J}from"@vkontakte/videoplayer-core/esnext.esm.js";var _;(function(t){t.PROD="prod",t.VK_ALIAS="vk_alias",t.VIDEOTEST="videotest",t.TEST="test",t.AUTO="auto"})(_||(_={}));var m;(function(t){t.Q144P="mobile",t.Q240P="lowest",t.Q360P="low",t.Q480P="medium",t.Q720P="high",t.Q1080P="fullhd",t.Q1440P="quadhd",t.Q2160P="ultrahd",t.UNKNOWN="unknown"})(m||(m={}));var g;(function(t){t.MP4="mp4",t.DASH="dash",t.DASH_SEP="dash_sep",t.ONDEMAND_DASH="ondemand_dash",t.HLS="hls",t.ONDEMAND_HLS="ondemand_hls",t.WEBM="webm",t.AV1="av1",t.ONDEMAND_DASH_LIVE="ondemand_dash_live",t.ONDEMAND_HLS_LIVE="ondemand_hls_live",t.WEBRTC="webrtc",t.UNKNOWN="unknown",t.RTMP="rtmp"})(g||(g={}));var F;(function(t){t.AUTO="auto",t.MANUAL=""})(F||(F={}));var $;(function(t){t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3"})($||($={}));var E;(function(t){t[t.YES=1]="YES",t[t.NO=0]="NO"})(E||(E={}));var x;(function(t){t.EXCELLENT="excellent",t.GOOD="good",t.POOR="poor"})(x||(x={}));var P;(function(t){t.PIP="pip",t.FULLSCREEN="fullscreen",t.EXTERNAL="external",t.PREFETCH="prefetch",t.AIRPLAY="airplay",t.CHROMECAST="chromecast",t.INVISIBLE="invisible"})(P||(P={}));var B;(function(t){t.SLIDER="slider",t.DOUBLE_TAP="double_tap",t.TIME_CODE="time_code",t.EPISODE="episode",t.REWIND="rewind",t.LIVE="live",t.UNKNOWN="unknown"})(B||(B={}));var Z;(function(t){t.GRAPH_SHOW="iGraphShow",t.GRAPH_HIDE="iGraphHide",t.NEXT_AREA="iNextChapterArea",t.NEXT_BUTTON="iNextChapterBtn",t.WATCH_AGAIN="iWatchAgainBtn"})(Z||(Z={}));const Ee={action_play:"ap",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"},Ae={vsid:"si",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"},we={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},ye={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv"},ve={apiEnv:_.VK_ALIAS,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageInterval:15e3,disabledOperations:[],disabledCustomFields:[],shorten:!0,embedUrlParams:[],useBeacon:!0,synchronizeTime:!0,debugLog:!1,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1}},Pe=t=>le(t,ve);function Te(){const t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36);let i=0,s,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),s=i&15,i=i>>4,e[o]=t[o===19?s&3|8:s]);return e.join("")}const xe=t=>{const{operation:e,custom:i}=t,s=Object.fromEntries(Object.entries(i).map(([o,n])=>{const a=Ae[o]??o;let l=n;return n&&(o==="mode"?l=ye[n]??n:o==="quality"&&(l=we[n]??n)),[a,l]}));return{...t,operation:Ee[e]??e,custom:s}},ee="1.0.41",Oe="CIOPGQJGDIHBABABA",te={[_.PROD]:"https://api.ok.ru",[_.VK_ALIAS]:"https://api.mycdn.me",[_.VIDEOTEST]:"https://videotestapi.ok.ru/api",[_.TEST]:"https://apitest.ok.ru",[_.AUTO]:""};var v;(function(t){t[t.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",t[t.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",t[t.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",t[t.AUTH_LOGIN=401]="AUTH_LOGIN"})(v||(v={}));class Le{params;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new k(!1);backoffTimeoutId;constructor(e){this.params=e}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(e){const i="log.externalLog",s=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,s,o)||this.logRequest(e)}async logRequest(e){const i="log.externalLog",s=this.createLogParams(e),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;const n=async(a,l=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,s,o)}catch(u){if(!u||!("error_code"in u)){this.params.error$.next({id:"logRequestUnknown",category:b.NETWORK,message:`Unknown ${i} error`,thrown:u});return}const h=u?.error_code;switch(h){case v.PARAM_SESSION_EXPIRED:case v.PARAM_SESSION_KEY:case v.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),l>0?n(a,l-1):void 0;case v.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),l>0?n(a,l-1):void 0;default:{this.params.error$.next({id:`LogRequest#${h}`,category:b.EXTERNAL_API,message:`${i} error`,data:u});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){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${ee}`,platform:this.params.mobile?"M_WEB":"WEB",items:this.params.config.shorten?e.map(xe):e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const e=de(this.consequentAuthErrors,this.params.config.backoff);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(s=>this.params.error$.next({id:"AuthorizeBackoff",category:b.NETWORK,message:"Otherwise unhandled error in authorization",thrown:s})).finally(()=>this.backoffTimeoutId=0)},e))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.uuid,client_version:ee.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(s=>((!s||!s.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:b.EXTERNAL_API,message:"No session key",data:s}),this.sessionKey=s?.session_key??void 0,this.sessionKey)).catch(async s=>{this.sessionKey=void 0;const o=s?.error_code;switch(o){case v.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:b.EXTERNAL_API,message:"authorize error",data:s}):this.params.error$.next({id:"AuthorizeUnknown",category:b.NETWORK,message:"authorize error",thrown:s})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class se{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(e,i,s){e in this.listeners||(this.listeners[e]=[]),this.listeners[e].push({callback:i,options:s})}removeEventListener(e,i){if(!(e in this.listeners))return;const s=this.listeners[e];for(let o=0,n=s.length;o<n;o++)if(s[o].callback===i){s.splice(o,1);return}}dispatchEvent(e){if(!(e.type in this.listeners))return;const s=this.listeners[e.type].slice();for(let o=0,n=s.length;o<n;o++){const a=s[o];try{a.callback.call(this,e)}catch(l){Promise.resolve().then(()=>{throw l})}a.options&&a.options.once&&this.removeEventListener(e.type,a.callback)}return!e.defaultPrevented}}class ae extends se{constructor(){super(),this.listeners||se.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(e){e.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,e)),super.dispatchEvent(e)}}class Ne{constructor(){Object.defineProperty(this,"signal",{value:new ae,writable:!0,configurable:!0})}abort(e){let i;try{i=new Event("abort")}catch{typeof document<"u"?document.createEvent?(i=document.createEvent("Event"),i.initEvent("abort",!1,!1)):(i=document.createEventObject(),i.type="abort"):i={type:"abort",bubbles:!1,cancelable:!1}}let s=e;if(s===void 0)if(typeof document>"u")s=new Error("This operation was aborted"),s.name="AbortError";else try{s=new DOMException("signal is aborted without reason")}catch{s=new Error("This operation was aborted"),s.name="AbortError"}this.signal.reason=s,this.signal.dispatchEvent(i)}toString(){return"[object AbortController]"}}typeof Symbol<"u"&&Symbol.toStringTag&&(Ne.prototype[Symbol.toStringTag]="AbortController",ae.prototype[Symbol.toStringTag]="AbortSignal");function ce(t){return t.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof t.Request=="function"&&!t.Request.prototype.hasOwnProperty("signal")||!t.AbortController}function $e(t){typeof t=="function"&&(t={fetch:t});const{fetch:e,Request:i=e.Request,AbortController:s,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=t;if(!ce({fetch:e,Request:i,AbortController:s,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:e,Request:n};let n=i;(n&&!n.prototype.hasOwnProperty("signal")||o)&&(n=function(h,r){let c;r&&r.signal&&(c=r.signal,delete r.signal);const d=new i(h,r);return c&&Object.defineProperty(d,"signal",{writable:!1,enumerable:!1,configurable:!0,value:c}),d},n.prototype=i.prototype);const a=e;return{fetch:(u,h)=>{const r=n&&n.prototype.isPrototypeOf(u)?u.signal:h?h.signal:void 0;if(r){let c;try{c=new DOMException("Aborted","AbortError")}catch{c=new Error("Aborted"),c.name="AbortError"}if(r.aborted)return Promise.reject(c);const d=new Promise((A,O)=>{r.addEventListener("abort",()=>O(c),{once:!0})});return h&&h.signal&&delete h.signal,Promise.race([d,a(u,h)])}return a(u,h)},Request:n}}const z=ce({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),ue=z?$e({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,ie=z?ue.fetch:window.fetch;z?ue.Request:window.Request;class Ce{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(e){this.params=e,this.apiKey=e.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=te[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==_.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await ie(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}),te[_.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(e,i,s){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:e,queryParams:i,sessionKey:s}),n=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,n)}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,s){const o=p(),n=a=>{if(a instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(a.message)){this.params.error$.next({id:"Network",category:b.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:b.NETWORK,message:"Unhandled request error",thrown:a,data:{method:e,params:i,sessionKey:s,time:p()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),ie(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:i,sessionKey:s})}).then(a=>{const l=Number(a.headers.get("content-length"))===0,u=new Date(a.headers.get("date")??"").getTime(),h=p()-o;if(isFinite(u)&&this.timeSynchronisation?.addServerTime(u,h),!l)return a.json().then(r=>Object.prototype.hasOwnProperty.call(r,"error_msg")?Promise.reject(r):r,n)},n)}_prepareQueryParams(e){const 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(([s,o])=>i.append(s,typeof o=="string"?o:JSON.stringify(o))),i}}const C="onestat_events",H=t=>e=>e.timestamp+t>=p();class Re{params;api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;firstFlush;debouncedFlush;loggerDebugLog;constructor(e){this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=X(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});const i=y.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=X(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=e=>{const{operation:i,custom:{param:s}}=e;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&s==="0-0"};safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:b.WTF,message:String(e)??"Unknown logger error",thrown:e})}}readFromStorage(){const e=y.get(C);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}const i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(H(this.params.config.storageExpiration));y.set(C,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(H(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const e=this.readFromStorage();delete e[this.userSalt],y.set(C,JSON.stringify(e))}housekeepStorage(){const e=this.readFromStorage();for(const[i,s]of Object.entries(e)){const o=s.filter(H(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${s.length} retrieved from storage, ${o.length} of them actual`})}y.set(C,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(e=!1){const i=this.getFromStorage();i.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${i.length} events through beacon`}),this.api.logBeacon(i)):(this.loggerDebugLog({message:`Flushing ${i.length} events`}),this.api.logRequest(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()}}const ke=()=>{let t,e;try{t=window.self!==window.top}catch(s){s instanceof DOMException&&s.name==="SecurityError"?t=!0:(t=!1,console.error(s))}try{window.location.ancestorOrigins&&(e=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(s){console.error(s)}try{!e&&document.referrer&&(e=document.referrer)}catch(s){console.error(s)}const i=e?new URL(e).hostname:void 0;return{isEmbed:t,host:i}},Ie=t=>t&&{[S.INVARIANT]:m.UNKNOWN,[S.Q_144P]:m.Q144P,[S.Q_240P]:m.Q240P,[S.Q_360P]:m.Q360P,[S.Q_480P]:m.Q480P,[S.Q_720P]:m.Q720P,[S.Q_1080P]:m.Q1080P,[S.Q_1440P]:m.Q1440P,[S.Q_2160P]:m.Q2160P,[S.Q_4320P]:m.UNKNOWN}[t],oe=t=>t&&{[q.HTTP1]:$.HTTP1,[q.HTTP2]:$.HTTP2,[q.QUIC]:$.HTTP3}[t],De=t=>{if(t!==void 0)switch(t){case f.MPEG:return g.MP4;case f.DASH:case f.DASH_LIVE:return g.DASH;case f.DASH_SEP:return g.DASH_SEP;case f.DASH_ONDEMAND:return g.ONDEMAND_DASH;case f.DASH_WEBM:case f.DASH_LIVE_WEBM:return g.WEBM;case f.DASH_WEBM_AV1:return g.AV1;case f.DASH_LIVE_CMAF:return g.ONDEMAND_DASH_LIVE;case f.HLS:case f.HLS_LIVE:return g.HLS;case f.HLS_ONDEMAND:return g.ONDEMAND_HLS;case f.HLS_LIVE_CMAF:return g.ONDEMAND_HLS_LIVE;case f.WEB_RTC_LIVE:return g.WEBRTC;default:return re(t)}},M=t=>{if(t!==void 0)switch(t){case N.NONE:case N.INLINE:return;case N.FULLSCREEN:return P.FULLSCREEN;case N.SECOND_SCREEN:return P.CHROMECAST;case N.PIP:return P.PIP;default:return re(t)}},Fe=t=>{switch(t){case"slow-2g":return x.POOR;case"2g":return x.POOR;case"3g":return x.GOOD;case"4g":return x.EXCELLENT}};class Be{offset=void 0;constructor(e){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){const s=Date.now(),o=e-s-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)}}const Ue=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),qe=(t,e)=>new fe(i=>{const s=new I,o=R(K(window,"beforeunload"),t.events.willDestruct$),n=new k(void 0);let a;s.add(t.info.isLive$.pipe(ge()).subscribe(w=>{a&&(a.unsubscribe(),n.next(void 0)),w?a=t.info.liveTime$.pipe(pe(U=>U&&U/1e3)).subscribe(n):a=t.info.position$.subscribe(n),s.add(a)}));const{playing$:l,paused$:u}=t.events,h=t.events.willSeek$.pipe(G(()=>t.info.playbackState$.getValue()===J.PLAYING)),r=t.events.seeked$.pipe(G(()=>t.info.playbackState$.getValue()===J.PLAYING));let c=!1;const d=new ne;s.add(h.subscribe(()=>{c||d.next(),c=!0})),s.add(r.subscribe(()=>c=!1));const A=R(l,r),O=R(u,d,o,t.events.looped$);let L;const Q=()=>L=n.getValue(),j=()=>{const w=n.getValue();D(L)||L===w||D(w)||(i.next({from:L,to:w}),L=void 0)},he=()=>{j(),Q()};if(s.add(A.subscribe(Q)),s.add(O.subscribe(j)),e.forceInterval&&isFinite(e.forceInterval)){let w=0;s.add(A.subscribe(()=>w=window.setTimeout(he,e.forceInterval))),s.add(O.subscribe(()=>window.clearTimeout(w)))}return s}),He="_one-stat_",W=`${He}uuid`,V=()=>{const t=new I;return{subscription:t,subscribe:(e,i)=>{e&&t.add(e.subscribe(i))}}};class Ke{api;logger;config;subscription=new I;beforeunloadSubscription;timeSynchronisation;debugLogger=new me;oneStatDebugLog=this.debugLogger.createComponentLog("onestat");experimental;vsid$=new k(void 0);statContext;isEmbed;embedParent;uiEvents;player;seekAction$=new k(B.UNKNOWN);uuid;constructor(e,i){this.statContext=e,this.config=Pe(i.config??{}),T(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new Be);const s=new ne;this.experimental={error$:s};const o=y.get(W);o?o.startsWith('"')&&o.endsWith('"')?(this.uuid=o.replaceAll('"',""),y.set(W,this.uuid)):this.uuid=o:(this.uuid=Te(),y.set(W,this.uuid)),this.resetViewSession();const n=new Ce({apiKey:Oe,config:this.config,error$:s,timeSynchronisation:this.timeSynchronisation});this.api=new Le({config:this.config,apiTransport:n,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,uuid:this.uuid,error$:s}),this.logger=new Re({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:s,userSalt:i.userSalt});const{isEmbed:a,host:l}=ke();this.isEmbed=a,this.embedParent=l,this.subscribe()}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){const i=new I,s=(r,c)=>i.add(r.subscribe(c));s(e.events.willStart$,()=>{const r=e.info.position$.getValue();this.logActionPlay({position:r}),this.statContext.projectId&&this.logActionPlayWithProjectId({position:r})}),s(e.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:e.info.position$.getValue()})}),s(e.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:e.info.position$.getValue()}),this.seekAction$.next(B.UNKNOWN)}),s(e.events.paused$,()=>{this.logPause({position:e.info.position$.getValue()})}),s(e.events.willResume$,()=>{this.logPlay()}),s(e.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),s(qe(e,{forceInterval:this.config.watchCoverageInterval}),r=>{const c=e.info.isLive$.getValue(),d={start:parseFloat(r.from.toFixed(3)),end:parseFloat(r.to.toFixed(3))};c?this.logWatchCoverageLive(d):this.logWatchCoverageRecord(d)});let o;s(e.info.isStalled$,r=>{r?o=p():(T(o)&&this.logEmptyBuffer({duration:p()-o}),o=void 0)});let n=!1;i.add(e.events.fatalError$.pipe(be()).subscribe(()=>n=!0)),s(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){const c=T(o)?p()-o:void 0;this.logCloseAtEmptyBuffer({duration:c??0}),o=void 0}else n||this.logActionStop()}),s(e.events.managedError$,({id:r})=>{this.logError({fatal:!1,errorType:r})}),s(e.events.fatalError$,({id:r})=>{this.logError({fatal:!0,errorType:r})});let a,l,u=!1;s(e.events.firstBytes$,r=>{a=p(),this.logFirstBytes({time:r})}),s(e.events.willStart$,()=>l=p()),s(e.info.currentBuffer$,r=>{!u&&r&&r.end-r.start>0&&T(a)&&(this.logPlayerReady({duration:p()-a}),u=!0)}),s(e.events.firstFrame$,()=>{T(a)&&!u&&(this.logPlayerReady({duration:p()-a}),u=!0),T(l)&&this.logFirstFrame({time:p()-l})}),s(e.info.atLiveEdge$,r=>this.updateContext({liveEdge:r})),s(Y({muted:e.info.muted$,volume:e.info.volume$}),({muted:r,volume:c})=>this.updateContext({audible:!r&&c>0})),s(e.info.currentQuality$,r=>this.updateContext({quality:Ie(r)})),s(e.info.isAutoQualityEnabled$,r=>this.updateContext({autoQuality:r})),s(e.info.currentFormat$,r=>this.updateContext({contentType:De(r)})),s(e.info.currentPlaybackRate$,r=>this.updateContext({rate:r})),s(e.info.is3DVideo$,r=>this.updateContext({is3d:r}));let h;return s(e.info.hostname$,r=>{this.updateContext({cdnHostname:r,failover:h!==void 0&&h!==r}),h=r}),s(e.info.throughputEstimation$,r=>this.updateContext({downloadSpeed:r})),s(e.info.httpConnectionType$,r=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:oe(r)}),this.updateContext({connectionType:oe(r)})}),s(e.info.httpConnectionReused$,r=>{D(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:r}),this.updateContext({connectionReused:r})}),s(e.info.surface$,r=>this.updateContext({mode:M(r)})),s(Y({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:r,available:c})=>{const d=c.find(({id:A})=>A===r);this.updateContext({subtitles:d?.language})}),this.player=e,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(e){this.uiEvents=e;const{subscription:i,subscribe:s}=V();return this.player&&(s(e.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),s(e.actionSeek$,this.seekAction$),s(e.inPiP$,o=>{const n=o?P.PIP:M(this.player?.info.surface$.getValue());this.updateContext({mode:n})}),s(e.inFullscreen$,o=>{const n=o?P.FULLSCREEN:M(this.player?.info.surface$.getValue());this.updateContext({mode:n})}),s(e.actionSetSubtitle$,o=>this.updateContext({subtitles:o})),s(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i)),i}attachToAds(e){const{subscription:i,subscribe:s}=V();return s(e.slotRequested$,()=>this.logAdSlotRequest()),s(e.started$,o=>this.logAdStarted(o)),s(e.paused$,()=>this.logAdPaused()),s(e.resumed$,()=>this.logAdResumed()),s(e.ended$,()=>this.logAdEnded()),s(e.skipped$,()=>this.logAdSkipped()),s(e.clicked$,()=>this.logAdClicked()),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToInteractive(e){const{subscription:i,subscribe:s}=V();return s(e.click$,o=>this.logInterfaceClick(o)),s(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(Ue())}getDeviceId(){return this.uuid}setFieldBlacklist(){}logInited(){}logReady(e){this.log({operation:"player_ready",param:String(e.time)})}logStarted(...e){this.logActionPlay(...e)}logPlay(){this.log({operation:"play_toggle"})}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}`})}logWatchCoverageLive(e){const i=this.timeSynchronisation?.getOffset()??0,s=e.start+i,o=e.end+i;this.log({operation:"watch_coverage_live",param:`${s}-${o}`})}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();const e=window.navigator.connection;e&&"onchange"in e&&"effectiveType"in e&&this.subscription.add(R(K(e,"change"),Se(["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=K(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),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))})}logActionPlayWithProjectId(e){this.statContext.projectId&&this.log({operation:"action_play",param:String(Math.round(e.position))},{vid:this.statContext.projectId})}logCloseAtEmptyBuffer(e){this.log({operation:"close_at_empty_buffer",param:String(Math.round(e.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(e,i={}){if(this.config.disabledOperations.includes(e.operation))return;this.oneStatDebugLog({message:`operation ${e.operation} ${e.param}`});const s=this.createLogItem(e,i);this.logger.log(s)}createLogItem({operation:e,param:i,time:s},o={}){const n=this.timeSynchronisation?.now()??p(),a=this.vsid$.getValue();_e(a);const l=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,u=this.statContext.firstConnectionReused;let h,r;if(this.isEmbed){h=this.embedParent;const d=[...new URLSearchParams(location.search).entries()].filter(([A,O])=>this.config.embedUrlParams.includes(A));r=new URLSearchParams(d).toString()}else this.statContext.place==="direct"&&(document.referrer&&(h=new URL(document.referrer).hostname),r=location.href.substring(0,1024));const c={vsid:a,vid:this.statContext.movieId,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?F.AUTO:this.statContext.autoplay===!1?F.MANUAL:void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:l,connection_reused:u===!0?E.YES:u===!1?E.NO:void 0,cached_data:this.statContext.cached===!0?E.YES:this.statContext.cached===!1?E.NO:void 0,live:this.statContext.liveEdge?E.YES:void 0,muted:this.statContext.audible===!1?E.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:E.YES,ref_domain:h,direct_url:r,rate:this.statContext.rate===1||D(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(const d of this.config.disabledCustomFields)delete c[d];return{operation:e,type:1,time:s,network:this.statContext.network,timestamp:n,custom:c}}}export{_ as ApiEnv,$ as ConnectionType,g as ContentType,Z as InteractiveInterfaceClick,Ke as OneStat,m as Quality,B as SeekAction,ee as VERSION};
package/evergreen.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @vkontakte/videoplayer-statistics v1.0.41-beta.2
3
- * Tue, 10 Oct 2023 08:39:46 GMT
2
+ * @vkontakte/videoplayer-statistics v1.0.41
3
+ * Mon, 16 Oct 2023 13:03:33 GMT
4
4
  * https://st.mycdn.me/static/vkontakte-videoplayer/1-0-41/doc/
5
5
  */
6
- import{fillWithDefault as st,ValueSubject as K,safeStorage as A,getExponentialDelay as it,ErrorCategory as m,now as l,assertNever as tt,Observable as ot,Subscription as R,merge as O,fromEvent as M,filterChanged as nt,map as rt,filter as z,Subject as et,isNullable as V,isNonNullable as w,once as at,combine as q,observableFrom as ht}from"@vkontakte/videoplayer-shared/esnext.esm.js";import Q from"lodash/debounce.js";import{Surface as v,VideoQuality as S,HttpConnectionType as B,VideoFormat as c,PlaybackState as G}from"@vkontakte/videoplayer-core/esnext.esm.js";var b;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(b||(b={}));var p;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(p||(p={}));var d;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.AV1="av1",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(d||(d={}));var C;(function(e){e.AUTO="auto",e.MANUAL=""})(C||(C={}));var $;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})($||($={}));var E;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(E||(E={}));var y;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(y||(y={}));var T;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(T||(T={}));var I;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(I||(I={}));var j;(function(e){e.GRAPH_SHOW="iGraphShow",e.GRAPH_HIDE="iGraphHide",e.NEXT_AREA="iNextChapterArea",e.NEXT_BUTTON="iNextChapterBtn",e.WATCH_AGAIN="iWatchAgainBtn"})(j||(j={}));const ut={apiEnv:b.VK_ALIAS,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,disabledOperations:[],disabledCustomFields:[],useBeacon:!0,synchronizeTime:!0,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1}},ct=e=>st(e,ut);function dt(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let i=0,s,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),s=i&15,i=i>>4,t[o]=e[o===19?s&3|8:s]);return t.join("")}const Y="1.0.41-beta.2",lt="CIOPGQJGDIHBABABA",X={[b.PROD]:"https://api.ok.ru",[b.VK_ALIAS]:"https://api.mycdn.me",[b.VIDEOTEST]:"https://videotestapi.ok.ru/api",[b.TEST]:"https://apitest.ok.ru",[b.AUTO]:""},ft="_one-stat_",U=`${ft}uuid`;var _;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(_||(_={}));class pt{params;uuid;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new K(!1);backoffTimeoutId;constructor(t){this.params=t;const i=A.get(U);i?i.startsWith('"')&&i.endsWith('"')?(this.uuid=i.replaceAll('"',""),A.set(U,this.uuid)):this.uuid=i:(this.uuid=dt(),A.set(U,this.uuid))}async authorize(t){return this.authToken=t??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const i="log.externalLog",s=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,s,o)||this.logRequest(t)}async logRequest(t){const i="log.externalLog",s=this.createLogParams(t),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;const r=async(a,u=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,s,o)}catch(h){if(!h||!("error_code"in h)){this.params.error$.next({id:"logRequestUnknown",category:m.NETWORK,message:`Unknown ${i} error`,thrown:h});return}const g=h?.error_code;switch(g){case _.PARAM_SESSION_EXPIRED:case _.PARAM_SESSION_KEY:case _.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),u>0?r(a,u-1):void 0;case _.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),u>0?r(a,u-1):void 0;default:{this.params.error$.next({id:`LogRequest#${g}`,category:m.EXTERNAL_API,message:`${i} error`,data:h});return}}}};return r(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${Y}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=it(this.consequentAuthErrors,this.params.config.backoff);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(s=>this.params.error$.next({id:"AuthorizeBackoff",category:m.NETWORK,message:"Otherwise unhandled error in authorization",thrown:s})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",i={session_data:{version:2,device_id:this.uuid,client_version:Y.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(t,i).then(s=>((!s||!s.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:m.EXTERNAL_API,message:"No session key",data:s}),this.sessionKey=s?.session_key??void 0,this.sessionKey)).catch(async s=>{this.sessionKey=void 0;const o=s?.error_code;switch(o){case _.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:m.EXTERNAL_API,message:"authorize error",data:s}):this.params.error$.next({id:"AuthorizeUnknown",category:m.NETWORK,message:"authorize error",thrown:s})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class gt{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.config.apiEnv,this.apiBaseUrl=X[this.apiEnv],this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==b.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const t=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(t,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(t){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:m.NETWORK,message:"Unhandled resolve api base url error",thrown:t}),X[b.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,i,s){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:i,sessionKey:s}),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:m.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:t,params:i}})}return!1}async sendRequest(t,i,s){const o=l(),r=a=>{if(a instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(a.message)){this.params.error$.next({id:"Network",category:m.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:m.NETWORK,message:"Unhandled request error",thrown:a,data:{method:t,params:i,sessionKey:s,time:l()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),fetch(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:i,sessionKey:s})}).then(a=>{const u=Number(a.headers.get("content-length"))===0,h=new Date(a.headers.get("date")??"").getTime(),g=l()-o;if(isFinite(h)&&this.timeSynchronisation?.addServerTime(h,g),!u)return a.json().then(n=>Object.prototype.hasOwnProperty.call(n,"error_msg")?Promise.reject(n):n,r)},r)}_prepareQueryParams(t){const i=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&i.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([s,o])=>i.append(s,typeof o=="string"?o:JSON.stringify(o))),i}}const k="onestat_events",F=e=>t=>t.timestamp+e>=l();class mt{params;api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;firstFlush;debouncedFlush;constructor(t){this.params=t,this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.firstFlush=Q(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});const i=A.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=Q(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=t=>{const{operation:i,custom:{param:s}}=t;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&s==="0-0"};safeFlush(){try{this.flush()}catch(t){this.error$.next({id:"LoggerError",category:m.WTF,message:String(t)??"Unknown logger error",thrown:t})}}readFromStorage(){const t=A.get(k);try{return t?JSON.parse(t):{}}catch{}return{}}addToStorage(t){if(!this.userSalt){this.unsaltedStorage.push(t);return}const i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(F(this.params.config.storageExpiration));A.set(k,JSON.stringify({...i,[this.userSalt]:[...o,t]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(F(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],A.set(k,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[i,s]of Object.entries(t)){const o=s.filter(F(this.params.config.storageExpiration));o.length?t[i]=o:delete t[i]}A.set(k,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const i=this.getFromStorage();i.length!==0&&(this.api.authorized$.getValue()?(t&&this.params.config.useBeacon?this.api.logBeacon(i):this.api.logRequest(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()}}const St=()=>{let e,t;try{e=window.self!==window.top}catch(s){s instanceof DOMException&&s.name==="SecurityError"?e=!0:(e=!1,console.error(s))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(s){console.error(s)}try{!t&&document.referrer&&(t=document.referrer)}catch(s){console.error(s)}const i=t?new URL(t).hostname:void 0;return{isEmbed:e,host:i}},bt=e=>e&&{[S.INVARIANT]:p.UNKNOWN,[S.Q_144P]:p.Q144P,[S.Q_240P]:p.Q240P,[S.Q_360P]:p.Q360P,[S.Q_480P]:p.Q480P,[S.Q_720P]:p.Q720P,[S.Q_1080P]:p.Q1080P,[S.Q_1440P]:p.Q1440P,[S.Q_2160P]:p.Q2160P,[S.Q_4320P]:p.UNKNOWN}[e],J=e=>e&&{[B.HTTP1]:$.HTTP1,[B.HTTP2]:$.HTTP2,[B.QUIC]:$.HTTP3}[e],Et=e=>{if(e!==void 0)switch(e){case c.MPEG:return d.MP4;case c.DASH:case c.DASH_LIVE:return d.DASH;case c.DASH_SEP:return d.DASH_SEP;case c.DASH_ONDEMAND:return d.ONDEMAND_DASH;case c.DASH_WEBM:case c.DASH_LIVE_WEBM:return d.WEBM;case c.DASH_WEBM_AV1:return d.AV1;case c.DASH_LIVE_CMAF:return d.ONDEMAND_DASH_LIVE;case c.HLS:case c.HLS_LIVE:return d.HLS;case c.HLS_ONDEMAND:return d.ONDEMAND_HLS;case c.HLS_LIVE_CMAF:return d.ONDEMAND_HLS_LIVE;case c.WEB_RTC_LIVE:return d.WEBRTC;default:return tt(e)}},W=e=>{if(e!==void 0)switch(e){case v.NONE:case v.INLINE:return;case v.FULLSCREEN:return T.FULLSCREEN;case v.SECOND_SCREEN:return T.EXTERNAL;case v.PIP:return T.PIP;default:return tt(e)}},At=e=>{switch(e){case"slow-2g":return y.POOR;case"2g":return y.POOR;case"3g":return y.GOOD;case"4g":return y.EXCELLENT}};class _t{offset=void 0;constructor(t){this.offset=t}getOffset(){return this.offset??0}setOffset(t){this.offset=t}now(){return Date.now()+(this.offset??0)}date(t=new Date){return t.setTime(t.getTime()+(this.offset??0)),t}addServerTime(t,i){const s=Date.now(),o=t-s-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)}}const Z=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),Tt=e=>new ot(t=>{const i=new R,s=O(M(window,"beforeunload"),e.events.willDestruct$),o=new K(void 0);let r;i.add(e.info.isLive$.pipe(nt()).subscribe(N=>{r&&(r.unsubscribe(),o.next(void 0)),N?r=e.info.liveTime$.pipe(rt(D=>D&&D/1e3)).subscribe(o):r=e.info.position$.subscribe(o),i.add(r)}));const{playing$:a,paused$:u}=e.events,h=e.events.willSeek$.pipe(z(()=>e.info.playbackState$.getValue()===G.PLAYING)),g=e.events.seeked$.pipe(z(()=>e.info.playbackState$.getValue()===G.PLAYING));let n=!1;const f=new et;i.add(h.subscribe(()=>{n||f.next(),n=!0})),i.add(g.subscribe(()=>n=!1));const P=O(a,g),L=O(u,f,s,e.events.looped$);let x;return i.add(P.subscribe(()=>x=o.getValue())),i.add(L.subscribe(()=>{const N=o.getValue();V(x)||x===N||V(N)||(t.next({from:x,to:N}),x=void 0)})),i}),H=()=>{const e=new R;return{subscription:e,subscribe:(t,i)=>{t&&e.add(t.subscribe(i))}}};class xt{api;logger;config;subscription=new R;beforeunloadSubscription;timeSynchronisation;experimental;statContext;vsid=Z();isEmbed;embedParent;uiEvents;player;seekAction$=new K(I.UNKNOWN);constructor(t,i){this.statContext=t,this.config=ct(i.config??{}),w(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new _t);const s=new et;this.experimental={error$:s};const o=new gt({apiKey:lt,config:this.config,error$:s,timeSynchronisation:this.timeSynchronisation});this.api=new pt({config:this.config,apiTransport:o,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,error$:s}),this.logger=new mt({config:this.config,api:this.api,error$:s,userSalt:i.userSalt});const{isEmbed:r,host:a}=St();this.isEmbed=r,this.embedParent=a,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const i=new R,s=(n,f)=>i.add(n.subscribe(f));s(t.events.willStart$,()=>{const n=t.info.position$.getValue();this.logActionPlay({position:n}),this.statContext.projectId&&this.logActionPlayWithProjectId({position:n})}),s(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),s(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(I.UNKNOWN)}),s(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),s(t.events.willResume$,()=>{this.logPlay()}),s(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),s(Tt(t),n=>{const f=t.info.isLive$.getValue(),P={start:parseFloat(n.from.toFixed(3)),end:parseFloat(n.to.toFixed(3))};f?this.logWatchCoverageLive(P):this.logWatchCoverageRecord(P)});let o;s(t.info.isStalled$,n=>{n?o=l():(w(o)&&this.logEmptyBuffer({duration:l()-o}),o=void 0)});let r=!1;i.add(t.events.fatalError$.pipe(at()).subscribe(()=>r=!0)),s(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const f=w(o)?l()-o:void 0;this.logCloseAtEmptyBuffer({duration:f??0}),o=void 0}else r||this.logActionStop()}),s(t.events.managedError$,({id:n})=>{this.logError({fatal:!1,errorType:n})}),s(t.events.fatalError$,({id:n})=>{this.logError({fatal:!0,errorType:n})});let a,u,h=!1;s(t.events.firstBytes$,n=>{a=l(),this.logFirstBytes({time:n})}),s(t.events.willStart$,()=>u=l()),s(t.info.currentBuffer$,n=>{!h&&n&&n.end-n.start>0&&w(a)&&(this.logPlayerReady({duration:l()-a}),h=!0)}),s(t.events.firstFrame$,()=>{w(a)&&!h&&(this.logPlayerReady({duration:l()-a}),h=!0),w(u)&&this.logFirstFrame({time:l()-u})}),s(t.info.atLiveEdge$,n=>this.updateContext({liveEdge:n})),s(q({muted:t.info.muted$,volume:t.info.volume$}),({muted:n,volume:f})=>this.updateContext({audible:!n&&f>0})),s(t.info.currentQuality$,n=>this.updateContext({quality:bt(n)})),s(t.info.isAutoQualityEnabled$,n=>this.updateContext({autoQuality:n})),s(t.info.currentFormat$,n=>this.updateContext({contentType:Et(n)}));let g;return s(t.info.hostname$,n=>{this.updateContext({cdnHostname:n,failover:g!==void 0&&g!==n}),g=n}),s(t.info.throughputEstimation$,n=>this.updateContext({downloadSpeed:n})),s(t.info.httpConnectionType$,n=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:J(n)}),this.updateContext({connectionType:J(n)})}),s(t.info.httpConnectionReused$,n=>{V(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:n}),this.updateContext({connectionReused:n})}),s(t.info.surface$,n=>this.updateContext({mode:W(n)})),s(q({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:n,available:f})=>{const P=f.find(({id:L})=>L===n);this.updateContext({subtitles:P?.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(t){this.uiEvents=t;const{subscription:i,subscribe:s}=H();return this.player&&(s(t.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),s(t.actionSeek$,this.seekAction$),s(t.inPiP$,o=>{const r=o?T.PIP:W(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),s(t.inFullscreen$,o=>{const r=o?T.FULLSCREEN:W(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),s(t.actionSetSubtitle$,o=>this.updateContext({subtitles:o})),s(t.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i)),i}attachToAds(t){const{subscription:i,subscribe:s}=H();return s(t.slotRequested$,()=>this.logAdSlotRequest()),s(t.started$,o=>this.logAdStarted(o)),s(t.paused$,()=>this.logAdPaused()),s(t.resumed$,()=>this.logAdResumed()),s(t.ended$,()=>this.logAdEnded()),s(t.skipped$,()=>this.logAdSkipped()),s(t.clicked$,()=>this.logAdClicked()),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToInteractive(t){const{subscription:i,subscribe:s}=H();return s(t.click$,o=>this.logInterfaceClick(o)),s(t.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i),i}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=Z()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const i=this.timeSynchronisation?.getOffset()??0,s=t.start+i,o=t.end+i;this.log({operation:"watch_coverage_live",param:`${s}-${o}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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(t){this.log({operation:"player_interface_click",param:t})}logNextMovie(t){this.log({operation:"next_movie",param:String(t)})}subscribe(){this.resubscribeBeforeunload();const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(O(M(t,"change"),ht(["init"])).subscribe(()=>this.updateContext({network:At(t.effectiveType)})))}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=M(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logActionPlayWithProjectId(t){if(!this.statContext.projectId)return;const i=this.createLogItem({operation:"action_play",param:String(Math.round(t.position))});i.custom.vid=this.statContext.projectId,this.logger.log(i)}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){if(this.config.disabledOperations.includes(t.operation))return;const i=this.createLogItem(t);this.logger.log(i)}createLogItem({operation:t,param:i,time:s}){const o=this.timeSynchronisation?.now()??l(),r=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,a=this.statContext.firstConnectionReused,u={vsid:this.vsid,vid:this.statContext.movieId,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?C.AUTO:this.statContext.autoplay===!1?C.MANUAL:void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:r,connection_reused:a===!0?E.YES:a===!1?E.NO:void 0,cached_data:this.statContext.cached===!0?E.YES:this.statContext.cached===!1?E.NO:void 0,live:this.statContext.liveEdge?E.YES:void 0,muted:this.statContext.audible===!1?E.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:E.YES,ref_domain:this.isEmbed?this.embedParent:this.statContext.refUrl,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};for(const h of this.config.disabledCustomFields)delete u[h];return{operation:t,type:1,time:s,network:this.statContext.network,timestamp:o,custom:u}}}export{b as ApiEnv,$ as ConnectionType,d as ContentType,j as InteractiveInterfaceClick,xt as OneStat,p as Quality,I as SeekAction,Y as VERSION};
6
+ import{fillWithDefault as nt,ValueSubject as O,getExponentialDelay as rt,ErrorCategory as b,now as g,safeStorage as w,assertNever as st,Observable as at,Subscription as I,merge as L,fromEvent as q,filterChanged as ct,map as ht,filter as G,Subject as it,isNullable as R,Logger as ut,isNonNullable as y,once as dt,combine as j,observableFrom as lt,assertNonNullable as ft}from"@vkontakte/videoplayer-shared/esnext.esm.js";import Y from"lodash/debounce.js";import{Surface as N,VideoQuality as S,HttpConnectionType as H,VideoFormat as l,PlaybackState as X}from"@vkontakte/videoplayer-core/esnext.esm.js";var _;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(_||(_={}));var p;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(p||(p={}));var f;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.AV1="av1",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(f||(f={}));var D;(function(e){e.AUTO="auto",e.MANUAL=""})(D||(D={}));var k;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})(k||(k={}));var A;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(A||(A={}));var x;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(x||(x={}));var T;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch",e.AIRPLAY="airplay",e.CHROMECAST="chromecast",e.INVISIBLE="invisible"})(T||(T={}));var B;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(B||(B={}));var J;(function(e){e.GRAPH_SHOW="iGraphShow",e.GRAPH_HIDE="iGraphHide",e.NEXT_AREA="iNextChapterArea",e.NEXT_BUTTON="iNextChapterBtn",e.WATCH_AGAIN="iWatchAgainBtn"})(J||(J={}));const gt={action_play:"ap",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"},pt={vsid:"si",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"},mt={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},bt={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv"},St={apiEnv:_.VK_ALIAS,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageInterval:15e3,disabledOperations:[],disabledCustomFields:[],shorten:!0,embedUrlParams:[],useBeacon:!0,synchronizeTime:!0,debugLog:!1,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1}},_t=e=>nt(e,St);function At(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let i=0,s,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),s=i&15,i=i>>4,t[o]=e[o===19?s&3|8:s]);return t.join("")}const Et=e=>{const{operation:t,custom:i}=e,s=Object.fromEntries(Object.entries(i).map(([o,r])=>{const a=pt[o]??o;let c=r;return r&&(o==="mode"?c=bt[r]??r:o==="quality"&&(c=mt[r]??r)),[a,c]}));return{...e,operation:gt[t]??t,custom:s}},Z="1.0.41",wt="CIOPGQJGDIHBABABA",tt={[_.PROD]:"https://api.ok.ru",[_.VK_ALIAS]:"https://api.mycdn.me",[_.VIDEOTEST]:"https://videotestapi.ok.ru/api",[_.TEST]:"https://apitest.ok.ru",[_.AUTO]:""};var P;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(P||(P={}));class Pt{params;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new O(!1);backoffTimeoutId;constructor(t){this.params=t}async authorize(t){return this.authToken=t??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const i="log.externalLog",s=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,s,o)||this.logRequest(t)}async logRequest(t){const i="log.externalLog",s=this.createLogParams(t),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;const r=async(a,c=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,s,o)}catch(h){if(!h||!("error_code"in h)){this.params.error$.next({id:"logRequestUnknown",category:b.NETWORK,message:`Unknown ${i} error`,thrown:h});return}const d=h?.error_code;switch(d){case P.PARAM_SESSION_EXPIRED:case P.PARAM_SESSION_KEY:case P.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),c>0?r(a,c-1):void 0;case P.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),c>0?r(a,c-1):void 0;default:{this.params.error$.next({id:`LogRequest#${d}`,category:b.EXTERNAL_API,message:`${i} error`,data:h});return}}}};return r(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${Z}`,platform:this.params.mobile?"M_WEB":"WEB",items:this.params.config.shorten?t.map(Et):t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=rt(this.consequentAuthErrors,this.params.config.backoff);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(s=>this.params.error$.next({id:"AuthorizeBackoff",category:b.NETWORK,message:"Otherwise unhandled error in authorization",thrown:s})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.uuid,client_version:Z.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(t,i).then(s=>((!s||!s.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:b.EXTERNAL_API,message:"No session key",data:s}),this.sessionKey=s?.session_key??void 0,this.sessionKey)).catch(async s=>{this.sessionKey=void 0;const o=s?.error_code;switch(o){case P.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:b.EXTERNAL_API,message:"authorize error",data:s}):this.params.error$.next({id:"AuthorizeUnknown",category:b.NETWORK,message:"authorize error",thrown:s})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class Tt{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.config.apiEnv,this.apiBaseUrl=tt[this.apiEnv],this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==_.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const t=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(t,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(t){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:b.NETWORK,message:"Unhandled resolve api base url error",thrown:t}),tt[_.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,i,s){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:i,sessionKey:s}),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:t,params:i}})}return!1}async sendRequest(t,i,s){const o=g(),r=a=>{if(a instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(a.message)){this.params.error$.next({id:"Network",category:b.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:b.NETWORK,message:"Unhandled request error",thrown:a,data:{method:t,params:i,sessionKey:s,time:g()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),fetch(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:i,sessionKey:s})}).then(a=>{const c=Number(a.headers.get("content-length"))===0,h=new Date(a.headers.get("date")??"").getTime(),d=g()-o;if(isFinite(h)&&this.timeSynchronisation?.addServerTime(h,d),!c)return a.json().then(n=>Object.prototype.hasOwnProperty.call(n,"error_msg")?Promise.reject(n):n,r)},r)}_prepareQueryParams(t){const i=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&i.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([s,o])=>i.append(s,typeof o=="string"?o:JSON.stringify(o))),i}}const C="onestat_events",W=e=>t=>t.timestamp+e>=g();class vt{params;api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;firstFlush;debouncedFlush;loggerDebugLog;constructor(t){this.params=t,this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.loggerDebugLog=t.debugLogger.createComponentLog("stat logger"),this.firstFlush=Y(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});const i=w.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=Y(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=t=>{const{operation:i,custom:{param:s}}=t;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&s==="0-0"};safeFlush(){try{this.flush()}catch(t){this.error$.next({id:"LoggerError",category:b.WTF,message:String(t)??"Unknown logger error",thrown:t})}}readFromStorage(){const t=w.get(C);try{return t?JSON.parse(t):{}}catch{}return{}}addToStorage(t){if(!this.userSalt){this.unsaltedStorage.push(t);return}const i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(W(this.params.config.storageExpiration));w.set(C,JSON.stringify({...i,[this.userSalt]:[...o,t]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(W(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],w.set(C,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[i,s]of Object.entries(t)){const o=s.filter(W(this.params.config.storageExpiration));o.length?t[i]=o:delete t[i],this.loggerDebugLog({message:`${s.length} retrieved from storage, ${o.length} of them actual`})}w.set(C,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const i=this.getFromStorage();i.length!==0&&(this.api.authorized$.getValue()?(t&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${i.length} events through beacon`}),this.api.logBeacon(i)):(this.loggerDebugLog({message:`Flushing ${i.length} events`}),this.api.logRequest(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()}}const yt=()=>{let e,t;try{e=window.self!==window.top}catch(s){s instanceof DOMException&&s.name==="SecurityError"?e=!0:(e=!1,console.error(s))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(s){console.error(s)}try{!t&&document.referrer&&(t=document.referrer)}catch(s){console.error(s)}const i=t?new URL(t).hostname:void 0;return{isEmbed:e,host:i}},xt=e=>e&&{[S.INVARIANT]:p.UNKNOWN,[S.Q_144P]:p.Q144P,[S.Q_240P]:p.Q240P,[S.Q_360P]:p.Q360P,[S.Q_480P]:p.Q480P,[S.Q_720P]:p.Q720P,[S.Q_1080P]:p.Q1080P,[S.Q_1440P]:p.Q1440P,[S.Q_2160P]:p.Q2160P,[S.Q_4320P]:p.UNKNOWN}[e],et=e=>e&&{[H.HTTP1]:k.HTTP1,[H.HTTP2]:k.HTTP2,[H.QUIC]:k.HTTP3}[e],$t=e=>{if(e!==void 0)switch(e){case l.MPEG:return f.MP4;case l.DASH:case l.DASH_LIVE:return f.DASH;case l.DASH_SEP:return f.DASH_SEP;case l.DASH_ONDEMAND:return f.ONDEMAND_DASH;case l.DASH_WEBM:case l.DASH_LIVE_WEBM:return f.WEBM;case l.DASH_WEBM_AV1:return f.AV1;case l.DASH_LIVE_CMAF:return f.ONDEMAND_DASH_LIVE;case l.HLS:case l.HLS_LIVE:return f.HLS;case l.HLS_ONDEMAND:return f.ONDEMAND_HLS;case l.HLS_LIVE_CMAF:return f.ONDEMAND_HLS_LIVE;case l.WEB_RTC_LIVE:return f.WEBRTC;default:return st(e)}},M=e=>{if(e!==void 0)switch(e){case N.NONE:case N.INLINE:return;case N.FULLSCREEN:return T.FULLSCREEN;case N.SECOND_SCREEN:return T.CHROMECAST;case N.PIP:return T.PIP;default:return st(e)}},Nt=e=>{switch(e){case"slow-2g":return x.POOR;case"2g":return x.POOR;case"3g":return x.GOOD;case"4g":return x.EXCELLENT}};class kt{offset=void 0;constructor(t){this.offset=t}getOffset(){return this.offset??0}setOffset(t){this.offset=t}now(){return Date.now()+(this.offset??0)}date(t=new Date){return t.setTime(t.getTime()+(this.offset??0)),t}addServerTime(t,i){const s=Date.now(),o=t-s-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)}}const Ct=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),Lt=(e,t)=>new at(i=>{const s=new I,o=L(q(window,"beforeunload"),e.events.willDestruct$),r=new O(void 0);let a;s.add(e.info.isLive$.pipe(ct()).subscribe(E=>{a&&(a.unsubscribe(),r.next(void 0)),E?a=e.info.liveTime$.pipe(ht(F=>F&&F/1e3)).subscribe(r):a=e.info.position$.subscribe(r),s.add(a)}));const{playing$:c,paused$:h}=e.events,d=e.events.willSeek$.pipe(G(()=>e.info.playbackState$.getValue()===X.PLAYING)),n=e.events.seeked$.pipe(G(()=>e.info.playbackState$.getValue()===X.PLAYING));let u=!1;const m=new it;s.add(d.subscribe(()=>{u||m.next(),u=!0})),s.add(n.subscribe(()=>u=!1));const v=L(c,n),U=L(h,m,o,e.events.looped$);let $;const z=()=>$=r.getValue(),Q=()=>{const E=r.getValue();R($)||$===E||R(E)||(i.next({from:$,to:E}),$=void 0)},ot=()=>{Q(),z()};if(s.add(v.subscribe(z)),s.add(U.subscribe(Q)),t.forceInterval&&isFinite(t.forceInterval)){let E=0;s.add(v.subscribe(()=>E=window.setTimeout(ot,t.forceInterval))),s.add(U.subscribe(()=>window.clearTimeout(E)))}return s}),Ot="_one-stat_",V=`${Ot}uuid`,K=()=>{const e=new I;return{subscription:e,subscribe:(t,i)=>{t&&e.add(t.subscribe(i))}}};class Bt{api;logger;config;subscription=new I;beforeunloadSubscription;timeSynchronisation;debugLogger=new ut;oneStatDebugLog=this.debugLogger.createComponentLog("onestat");experimental;vsid$=new O(void 0);statContext;isEmbed;embedParent;uiEvents;player;seekAction$=new O(B.UNKNOWN);uuid;constructor(t,i){this.statContext=t,this.config=_t(i.config??{}),y(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new kt);const s=new it;this.experimental={error$:s};const o=w.get(V);o?o.startsWith('"')&&o.endsWith('"')?(this.uuid=o.replaceAll('"',""),w.set(V,this.uuid)):this.uuid=o:(this.uuid=At(),w.set(V,this.uuid)),this.resetViewSession();const r=new Tt({apiKey:wt,config:this.config,error$:s,timeSynchronisation:this.timeSynchronisation});this.api=new Pt({config:this.config,apiTransport:r,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,uuid:this.uuid,error$:s}),this.logger=new vt({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:s,userSalt:i.userSalt});const{isEmbed:a,host:c}=yt();this.isEmbed=a,this.embedParent=c,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const i=new I,s=(n,u)=>i.add(n.subscribe(u));s(t.events.willStart$,()=>{const n=t.info.position$.getValue();this.logActionPlay({position:n}),this.statContext.projectId&&this.logActionPlayWithProjectId({position:n})}),s(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),s(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(B.UNKNOWN)}),s(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),s(t.events.willResume$,()=>{this.logPlay()}),s(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),s(Lt(t,{forceInterval:this.config.watchCoverageInterval}),n=>{const u=t.info.isLive$.getValue(),m={start:parseFloat(n.from.toFixed(3)),end:parseFloat(n.to.toFixed(3))};u?this.logWatchCoverageLive(m):this.logWatchCoverageRecord(m)});let o;s(t.info.isStalled$,n=>{n?o=g():(y(o)&&this.logEmptyBuffer({duration:g()-o}),o=void 0)});let r=!1;i.add(t.events.fatalError$.pipe(dt()).subscribe(()=>r=!0)),s(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const u=y(o)?g()-o:void 0;this.logCloseAtEmptyBuffer({duration:u??0}),o=void 0}else r||this.logActionStop()}),s(t.events.managedError$,({id:n})=>{this.logError({fatal:!1,errorType:n})}),s(t.events.fatalError$,({id:n})=>{this.logError({fatal:!0,errorType:n})});let a,c,h=!1;s(t.events.firstBytes$,n=>{a=g(),this.logFirstBytes({time:n})}),s(t.events.willStart$,()=>c=g()),s(t.info.currentBuffer$,n=>{!h&&n&&n.end-n.start>0&&y(a)&&(this.logPlayerReady({duration:g()-a}),h=!0)}),s(t.events.firstFrame$,()=>{y(a)&&!h&&(this.logPlayerReady({duration:g()-a}),h=!0),y(c)&&this.logFirstFrame({time:g()-c})}),s(t.info.atLiveEdge$,n=>this.updateContext({liveEdge:n})),s(j({muted:t.info.muted$,volume:t.info.volume$}),({muted:n,volume:u})=>this.updateContext({audible:!n&&u>0})),s(t.info.currentQuality$,n=>this.updateContext({quality:xt(n)})),s(t.info.isAutoQualityEnabled$,n=>this.updateContext({autoQuality:n})),s(t.info.currentFormat$,n=>this.updateContext({contentType:$t(n)})),s(t.info.currentPlaybackRate$,n=>this.updateContext({rate:n})),s(t.info.is3DVideo$,n=>this.updateContext({is3d:n}));let d;return s(t.info.hostname$,n=>{this.updateContext({cdnHostname:n,failover:d!==void 0&&d!==n}),d=n}),s(t.info.throughputEstimation$,n=>this.updateContext({downloadSpeed:n})),s(t.info.httpConnectionType$,n=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:et(n)}),this.updateContext({connectionType:et(n)})}),s(t.info.httpConnectionReused$,n=>{R(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:n}),this.updateContext({connectionReused:n})}),s(t.info.surface$,n=>this.updateContext({mode:M(n)})),s(j({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:n,available:u})=>{const m=u.find(({id:v})=>v===n);this.updateContext({subtitles:m?.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(t){this.uiEvents=t;const{subscription:i,subscribe:s}=K();return this.player&&(s(t.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),s(t.actionSeek$,this.seekAction$),s(t.inPiP$,o=>{const r=o?T.PIP:M(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),s(t.inFullscreen$,o=>{const r=o?T.FULLSCREEN:M(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),s(t.actionSetSubtitle$,o=>this.updateContext({subtitles:o})),s(t.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i)),i}attachToAds(t){const{subscription:i,subscribe:s}=K();return s(t.slotRequested$,()=>this.logAdSlotRequest()),s(t.started$,o=>this.logAdStarted(o)),s(t.paused$,()=>this.logAdPaused()),s(t.resumed$,()=>this.logAdResumed()),s(t.ended$,()=>this.logAdEnded()),s(t.skipped$,()=>this.logAdSkipped()),s(t.clicked$,()=>this.logAdClicked()),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToInteractive(t){const{subscription:i,subscribe:s}=K();return s(t.click$,o=>this.logInterfaceClick(o)),s(t.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i),i}authorize(t){return this.api.authorize(t)}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(Ct())}getDeviceId(){return this.uuid}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const i=this.timeSynchronisation?.getOffset()??0,s=t.start+i,o=t.end+i;this.log({operation:"watch_coverage_live",param:`${s}-${o}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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(t){this.log({operation:"player_interface_click",param:t})}logNextMovie(t){this.log({operation:"next_movie",param:String(t)})}subscribe(){this.resubscribeBeforeunload();const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(L(q(t,"change"),lt(["init"])).subscribe(()=>this.updateContext({network:Nt(t.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=q(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logActionPlayWithProjectId(t){this.statContext.projectId&&this.log({operation:"action_play",param:String(Math.round(t.position))},{vid:this.statContext.projectId})}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t,i={}){if(this.config.disabledOperations.includes(t.operation))return;this.oneStatDebugLog({message:`operation ${t.operation} ${t.param}`});const s=this.createLogItem(t,i);this.logger.log(s)}createLogItem({operation:t,param:i,time:s},o={}){const r=this.timeSynchronisation?.now()??g(),a=this.vsid$.getValue();ft(a);const c=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,h=this.statContext.firstConnectionReused;let d,n;if(this.isEmbed){d=this.embedParent;const m=[...new URLSearchParams(location.search).entries()].filter(([v,U])=>this.config.embedUrlParams.includes(v));n=new URLSearchParams(m).toString()}else this.statContext.place==="direct"&&(document.referrer&&(d=new URL(document.referrer).hostname),n=location.href.substring(0,1024));const u={vsid:a,vid:this.statContext.movieId,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?D.AUTO:this.statContext.autoplay===!1?D.MANUAL:void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:c,connection_reused:h===!0?A.YES:h===!1?A.NO:void 0,cached_data:this.statContext.cached===!0?A.YES:this.statContext.cached===!1?A.NO:void 0,live:this.statContext.liveEdge?A.YES:void 0,muted:this.statContext.audible===!1?A.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:A.YES,ref_domain:d,direct_url:n,rate:this.statContext.rate===1||R(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(const m of this.config.disabledCustomFields)delete u[m];return{operation:t,type:1,time:s,network:this.statContext.network,timestamp:r,custom:u}}}export{_ as ApiEnv,k as ConnectionType,f as ContentType,J as InteractiveInterfaceClick,Bt as OneStat,p as Quality,B as SeekAction,Z as VERSION};
package/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { Kbps, RecursivePartial, Milliseconds, IObservable, ISubscription, IError, Seconds } from '@vkontakte/videoplayer-shared';
1
+ import { Kbps, RecursivePartial, Milliseconds, IObservable, ISubscription, IError, IValueObservable, Seconds, ValueSubject } from '@vkontakte/videoplayer-shared';
2
2
  import { IPlayer } from '@vkontakte/videoplayer-core';
3
3
 
4
- type Operation = 'action_play' | 'first_bytes' | 'player_ready' | 'first_frame' | 'seek' | 'watch_coverage_record' | 'watch_coverage_live' | 'empty_buffer' | 'action_stop' | 'close_at_empty_buffer' | 'content_error' | 'player_interface_click' | 'next_movie' | 'play_toggle' | 'pause' | 'adv';
4
+ type Operation = 'action_play' | 'first_bytes' | 'player_ready' | 'first_frame' | 'seek' | 'watch_coverage_record' | 'watch_coverage_live' | 'empty_buffer' | 'action_stop' | 'close_at_empty_buffer' | 'content_error' | 'player_interface_click' | 'next_movie' | 'track_switch' | // Пока не поддержана
5
+ 'play_toggle' | 'pause' | 'adv';
5
6
  declare enum ApiEnv {
6
7
  PROD = "prod",
7
8
  VK_ALIAS = "vk_alias",
@@ -58,7 +59,10 @@ declare enum Mode {
58
59
  PIP = "pip",
59
60
  FULLSCREEN = "fullscreen",
60
61
  EXTERNAL = "external",
61
- PREFETCH = "prefetch"
62
+ PREFETCH = "prefetch",
63
+ AIRPLAY = "airplay",
64
+ CHROMECAST = "chromecast",
65
+ INVISIBLE = "invisible"
62
66
  }
63
67
  declare enum SeekAction {
64
68
  SLIDER = "slider",
@@ -104,6 +108,9 @@ interface ILogCustomData {
104
108
  download_speed?: Kbps;
105
109
  manual_quality?: Flag;
106
110
  ref_domain?: string;
111
+ direct_url?: string;
112
+ rate?: string;
113
+ view_360?: 1;
107
114
  vk_playlist_id?: string;
108
115
  aid?: string;
109
116
  }
@@ -115,10 +122,14 @@ interface IConfig {
115
122
  flushDebounceTime: Milliseconds;
116
123
  flushMaxWait: Milliseconds;
117
124
  storageExpiration: Milliseconds;
125
+ watchCoverageInterval: Milliseconds;
118
126
  disabledOperations: Operation[];
119
127
  disabledCustomFields: (keyof ILogCustomData)[];
128
+ shorten: boolean;
129
+ embedUrlParams: string[];
120
130
  useBeacon: boolean;
121
131
  synchronizeTime: boolean;
132
+ debugLog: boolean;
122
133
  backoff: {
123
134
  start: Milliseconds;
124
135
  factor: number;
@@ -182,6 +193,10 @@ interface IOneStat {
182
193
  * Сбрасывает сессию смотрения
183
194
  */
184
195
  resetViewSession(): void;
196
+ /**
197
+ * Идентификатор текущего устройства
198
+ */
199
+ getDeviceId(): string;
185
200
  /**
186
201
  * @deprecated
187
202
  * Отключает отправку полей событий
@@ -288,6 +303,7 @@ interface IOneStat {
288
303
  experimental: {
289
304
  error$: IObservable<IError>;
290
305
  };
306
+ vsid$: IValueObservable<string | undefined>;
291
307
  }
292
308
  interface IActionPlayPayload {
293
309
  /**
@@ -360,7 +376,6 @@ interface IStatContext {
360
376
  albumId?: string;
361
377
  vkPlaylistId?: string;
362
378
  trackCode?: string;
363
- refUrl?: string;
364
379
  place?: string;
365
380
  cdnHostname?: string;
366
381
  downloadSpeed?: Kbps;
@@ -373,6 +388,8 @@ interface IStatContext {
373
388
  mode?: Mode;
374
389
  subtitles?: string;
375
390
  failover?: boolean;
391
+ rate?: number;
392
+ is3d?: boolean;
376
393
  }
377
394
  interface IConstructorParams {
378
395
  /** @deprecated Используете config.apiEnv */
@@ -392,16 +409,19 @@ declare class OneStat implements IOneStat {
392
409
  private subscription;
393
410
  private beforeunloadSubscription;
394
411
  private timeSynchronisation?;
412
+ private debugLogger;
413
+ private oneStatDebugLog;
395
414
  experimental: {
396
415
  error$: IObservable<IError>;
397
416
  };
417
+ vsid$: ValueSubject<string | undefined>;
398
418
  private statContext;
399
- private vsid;
400
419
  private isEmbed;
401
420
  private embedParent;
402
421
  private uiEvents;
403
422
  private player;
404
423
  private seekAction$;
424
+ private uuid;
405
425
  constructor(statContext: IStatContext, params: IConstructorParams);
406
426
  updateContext(newContext: Partial<IStatContext>): void;
407
427
  attachTo(player: IPlayer): ISubscription;
@@ -413,6 +433,7 @@ declare class OneStat implements IOneStat {
413
433
  resume(): void;
414
434
  destroy(): void;
415
435
  resetViewSession(): void;
436
+ getDeviceId(): string;
416
437
  setFieldBlacklist(): void;
417
438
  logInited(): void;
418
439
  logReady(payload: IReadyPayload): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vkontakte/videoplayer-statistics",
3
- "version": "1.0.41-beta.2",
3
+ "version": "1.0.41",
4
4
  "author": "vk.com",
5
5
  "description": "Statistics library for vk.com videoplayer",
6
6
  "homepage": "https://vk.com",
@@ -49,10 +49,10 @@
49
49
  "**/*.d.ts"
50
50
  ],
51
51
  "dependencies": {
52
- "@vkontakte/videoplayer-shared": "^1.0.29",
52
+ "@vkontakte/videoplayer-shared": "^1.0.30",
53
53
  "lodash": "4.17.21"
54
54
  },
55
55
  "peerDependencies": {
56
- "@vkontakte/videoplayer-core": "2.0.91-beta.2"
56
+ "@vkontakte/videoplayer-core": "^2.0.91"
57
57
  }
58
58
  }