bitmovin-analytics 2.53.1 → 2.53.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"bitmovin-analytics-bitmovin-player-web-x.js","mappings":"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KqgC,2BAAmB,SAAEjuB,QAC1BpS,KAAKsgC,WAAa,CACpB,EAEA,YAAAv2B,QAAA,WACE/J,KAAK4c,QAAQ7S,SAAU,EACvB/J,KAAK4c,QAAQijB,OACf,EAEA,YAAAlC,SAAA,e,EAAA,OACE39B,KAAKsgC,WAAa,EACM,QAAxB,EAAAtgC,KAAKqgC,2BAAmB,SAAE3C,UAC1B19B,KAAK4c,QAAQqjB,QACbjgC,KAAKogC,cAAcnT,SAAQ,SAAC0T,GAAiB,OAAAA,EAAatT,YAAY,EAAKkT,eAA9B,GAC/C,EAEA,YAAAvC,WAAA,SAAW4C,EAAyBp+B,G,QAC5B88B,EAAc3zB,KAAKsR,IAAgC,QAA5B,EAAAza,aAAM,EAANA,EAAQq+B,4BAAoB,QAAI,EAAG,GACxC,QAAxB,EAAA7gC,KAAKqgC,2BAAmB,SAAEzC,UAAU0B,GACpCt/B,KAAK4c,QAAQ2iB,sCAAsCD,EACrD,EAEA,YAAAvB,cAAA,SAAcD,GACZ,OAAOA,EAAgBgD,YACzB,EAsCF,EA5EA,CAfA,OAeyC7C,SAA5B,EAAAlwB,oBAAAA,C,mMCrBb,cA6Ga,EAAAknB,qBAAsD,CACjE,cACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBAEA,kBAMW,EAAA8L,qBAAuB,EAAA9L,qBAAqB/pB,QAAO,SAAC81B,GAAM,OAAAA,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","sources":["webpack://bitmovin.analytics/webpack/universalModuleDefinition","webpack://bitmovin.analytics/./node_modules/javascript-state-machine/state-machine.js","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/BitmovinPwxAdapter.ts","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/BitmovinPwxAnalyticsPackage.ts","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/BitmovinPwxAnalyticsStateMachine.ts","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/BitmovinPwxInternalAdapter.ts","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/ExportNames.ts","webpack://bitmovin.analytics/./src/adapters/internal/InternalAdapter.ts","webpack://bitmovin.analytics/./src/adapters/internal/ads/AdModuleAPI.ts","webpack://bitmovin.analytics/./src/analyticsStateMachines/AnalyticsStateMachine.ts","webpack://bitmovin.analytics/./src/analyticsStateMachines/stateMachineUtils.ts","webpack://bitmovin.analytics/./src/core/AdAnalytics.ts","webpack://bitmovin.analytics/./src/core/Analytics.ts","webpack://bitmovin.analytics/./src/core/BackendFactory.ts","webpack://bitmovin.analytics/./src/core/DebuggingBackend.ts","webpack://bitmovin.analytics/./src/core/EventDispatcher.ts","webpack://bitmovin.analytics/./src/core/HeartbeatService.ts","webpack://bitmovin.analytics/./src/core/IdenticalErrorReportingLimiter.ts","webpack://bitmovin.analytics/./src/core/LicenseCheckingBackend.ts","webpack://bitmovin.analytics/./src/core/LongPlaytimeFilteringBackend.ts","webpack://bitmovin.analytics/./src/core/NoOpBackend.ts","webpack://bitmovin.analytics/./src/core/QualityChangeService.ts","webpack://bitmovin.analytics/./src/core/QueueBackend.ts","webpack://bitmovin.analytics/./src/core/RemoteBackend.ts","webpack://bitmovin.analytics/./src/core/SequenceNumberBackend.ts","webpack://bitmovin.analytics/./src/core/SessionPersistenceHandler.ts","webpack://bitmovin.analytics/./src/core/SourceInfoFallbackService.ts","webpack://bitmovin.analytics/./src/core/ssai/SsaiService.ts","webpack://bitmovin.analytics/./src/core/ssai/ssaiEngagementInteractionData.ts","webpack://bitmovin.analytics/./src/core/ssai/ssaiUtils.ts","webpack://bitmovin.analytics/./src/enums/AdType.ts","webpack://bitmovin.analytics/./src/enums/CDNProvider.ts","webpack://bitmovin.analytics/./src/enums/ErrorCode.ts","webpack://bitmovin.analytics/./src/enums/Event.ts","webpack://bitmovin.analytics/./src/enums/MIMETypes.ts","webpack://bitmovin.analytics/./src/enums/PageLoadType.ts","webpack://bitmovin.analytics/./src/enums/Player.ts","webpack://bitmovin.analytics/./src/enums/PlayerSize.ts","webpack://bitmovin.analytics/./src/enums/StreamTypes.ts","webpack://bitmovin.analytics/./src/enums/VideoStartFailedReason.ts","webpack://bitmovin.analytics/./src/features/Feature.ts","webpack://bitmovin.analytics/./src/features/FeatureManager.ts","webpack://bitmovin.analytics/./src/features/errordetails/ErrorDetailBackend.ts","webpack://bitmovin.analytics/./src/features/errordetails/ErrorDetailTracking.ts","webpack://bitmovin.analytics/./src/types/CustomDataValues.ts","webpack://bitmovin.analytics/./src/types/LicensingRequest.ts","webpack://bitmovin.analytics/./src/types/PlaybackInfo.ts","webpack://bitmovin.analytics/./src/types/StateMachineCallbacks.ts","webpack://bitmovin.analytics/./src/utils/AnalyticsCall.ts","webpack://bitmovin.analytics/./src/utils/CodecHelper.ts","webpack://bitmovin.analytics/./src/utils/EventDebugging.ts","webpack://bitmovin.analytics/./src/utils/Http.ts","webpack://bitmovin.analytics/./src/utils/LicenseCall.ts","webpack://bitmovin.analytics/./src/utils/Logger.ts","webpack://bitmovin.analytics/./src/utils/Settings.ts","webpack://bitmovin.analytics/./src/utils/Utils.ts","webpack://bitmovin.analytics/./src/utils/Version.ts","webpack://bitmovin.analytics/./src/utils/ViewportTracker.ts","webpack://bitmovin.analytics/./src/utils/WebOSUtils.ts","webpack://bitmovin.analytics/./src/utils/WindowEventTracker.ts","webpack://bitmovin.analytics/./src/utils/analyticsConfigUtils.ts","webpack://bitmovin.analytics/./src/utils/collectorRequirementChecks.ts","webpack://bitmovin.analytics/./src/utils/documentUtils.ts","webpack://bitmovin.analytics/./src/utils/globalScope.ts","webpack://bitmovin.analytics/./src/utils/globalScopeUtils.ts","webpack://bitmovin.analytics/./src/utils/numberUtils.ts","webpack://bitmovin.analytics/./src/utils/objectUtils.ts","webpack://bitmovin.analytics/./src/utils/sampleUtils.ts","webpack://bitmovin.analytics/./src/utils/stringUtils.ts","webpack://bitmovin.analytics/./src/utils/uuidUtils.ts","webpack://bitmovin.analytics/webpack/bootstrap","webpack://bitmovin.analytics/webpack/runtime/global","webpack://bitmovin.analytics/./src/bitmovin-analytics-bitmovin-player-web-x.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"bitmovin\"] = factory();\n\telse\n\t\troot[\"bitmovin\"] = root[\"bitmovin\"] || {}, root[\"bitmovin\"][\"analytics\"] = factory();\n})(self, function() {\nreturn ","/*\n\n Javascript State Machine Library - https://github.com/jakesgordon/javascript-state-machine\n\n Copyright (c) 2012, 2013, 2014, 2015, Jake Gordon and contributors\n Released under the MIT license - https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE\n\n*/\n\n(function () {\n\n var StateMachine = {\n\n //---------------------------------------------------------------------------\n\n VERSION: \"2.4.0\",\n\n //---------------------------------------------------------------------------\n\n Result: {\n SUCCEEDED: 1, // the event transitioned successfully from one state to another\n NOTRANSITION: 2, // the event was successfull but no state transition was necessary\n CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback\n PENDING: 4 // the event is asynchronous and the caller is in control of when the transition occurs\n },\n\n Error: {\n INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state\n PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending\n INVALID_CALLBACK: 300 // caller provided callback function threw an exception\n },\n\n WILDCARD: '*',\n ASYNC: 'async',\n\n //---------------------------------------------------------------------------\n\n create: function(cfg, target) {\n\n var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false }\n var terminal = cfg.terminal || cfg['final'];\n var fsm = target || cfg.target || {};\n var events = cfg.events || [];\n var callbacks = cfg.callbacks || {};\n var map = {}; // track state transitions allowed for an event { event: { from: [ to ] } }\n var transitions = {}; // track events allowed from a state { state: [ event ] }\n\n var add = function(e) {\n var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified\n map[e.name] = map[e.name] || {};\n for (var n = 0 ; n < from.length ; n++) {\n transitions[from[n]] = transitions[from[n]] || [];\n transitions[from[n]].push(e.name);\n\n map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified\n }\n if (e.to)\n transitions[e.to] = transitions[e.to] || [];\n };\n\n if (initial) {\n initial.event = initial.event || 'startup';\n add({ name: initial.event, from: 'none', to: initial.state });\n }\n\n for(var n = 0 ; n < events.length ; n++)\n add(events[n]);\n\n for(var name in map) {\n if (map.hasOwnProperty(name))\n fsm[name] = StateMachine.buildEvent(name, map[name]);\n }\n\n for(var name in callbacks) {\n if (callbacks.hasOwnProperty(name))\n fsm[name] = callbacks[name]\n }\n\n fsm.current = 'none';\n fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); };\n fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); }\n fsm.cannot = function(event) { return !this.can(event); };\n fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); };\n fsm.isFinished = function() { return this.is(terminal); };\n fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17)\n fsm.states = function() { return Object.keys(transitions).sort() };\n\n if (initial && !initial.defer)\n fsm[initial.event]();\n\n return fsm;\n\n },\n\n //===========================================================================\n\n doCallback: function(fsm, func, name, from, to, args) {\n if (func) {\n try {\n return func.apply(fsm, [name, from, to].concat(args));\n }\n catch(e) {\n return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, \"an exception occurred in a caller-provided callback function\", e);\n }\n }\n },\n\n beforeAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbeforeevent'], name, from, to, args); },\n afterAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafterevent'] || fsm['onevent'], name, from, to, args); },\n leaveAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleavestate'], name, from, to, args); },\n enterAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenterstate'] || fsm['onstate'], name, from, to, args); },\n changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); },\n\n beforeThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); },\n afterThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); },\n leaveThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); },\n enterThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); },\n\n beforeEvent: function(fsm, name, from, to, args) {\n if ((false === StateMachine.beforeThisEvent(fsm, name, from, to, args)) ||\n (false === StateMachine.beforeAnyEvent( fsm, name, from, to, args)))\n return false;\n },\n\n afterEvent: function(fsm, name, from, to, args) {\n StateMachine.afterThisEvent(fsm, name, from, to, args);\n StateMachine.afterAnyEvent( fsm, name, from, to, args);\n },\n\n leaveState: function(fsm, name, from, to, args) {\n var specific = StateMachine.leaveThisState(fsm, name, from, to, args),\n general = StateMachine.leaveAnyState( fsm, name, from, to, args);\n if ((false === specific) || (false === general))\n return false;\n else if ((StateMachine.ASYNC === specific) || (StateMachine.ASYNC === general))\n return StateMachine.ASYNC;\n },\n\n enterState: function(fsm, name, from, to, args) {\n StateMachine.enterThisState(fsm, name, from, to, args);\n StateMachine.enterAnyState( fsm, name, from, to, args);\n },\n\n //===========================================================================\n\n buildEvent: function(name, map) {\n return function() {\n\n var from = this.current;\n var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from;\n var args = Array.prototype.slice.call(arguments); // turn arguments into pure array\n\n if (this.transition)\n return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, \"event \" + name + \" inappropriate because previous transition did not complete\");\n\n if (this.cannot(name))\n return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, \"event \" + name + \" inappropriate in current state \" + this.current);\n\n if (false === StateMachine.beforeEvent(this, name, from, to, args))\n return StateMachine.Result.CANCELLED;\n\n if (from === to) {\n StateMachine.afterEvent(this, name, from, to, args);\n return StateMachine.Result.NOTRANSITION;\n }\n\n // prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState)\n var fsm = this;\n this.transition = function() {\n fsm.transition = null; // this method should only ever be called once\n fsm.current = to;\n StateMachine.enterState( fsm, name, from, to, args);\n StateMachine.changeState(fsm, name, from, to, args);\n StateMachine.afterEvent( fsm, name, from, to, args);\n return StateMachine.Result.SUCCEEDED;\n };\n this.transition.cancel = function() { // provide a way for caller to cancel async transition if desired (issue #22)\n fsm.transition = null;\n StateMachine.afterEvent(fsm, name, from, to, args);\n }\n\n var leave = StateMachine.leaveState(this, name, from, to, args);\n if (false === leave) {\n this.transition = null;\n return StateMachine.Result.CANCELLED;\n }\n else if (StateMachine.ASYNC === leave) {\n return StateMachine.Result.PENDING;\n }\n else {\n if (this.transition) // need to check in case user manually called transition() but forgot to return StateMachine.ASYNC\n return this.transition();\n }\n\n };\n }\n\n }; // StateMachine\n\n //===========================================================================\n\n //======\n // NODE\n //======\n if (typeof exports !== 'undefined') {\n if (typeof module !== 'undefined' && module.exports) {\n exports = module.exports = StateMachine;\n }\n exports.StateMachine = StateMachine;\n }\n //============\n // AMD/REQUIRE\n //============\n else if (typeof define === 'function' && define.amd) {\n define(function(require) { return StateMachine; });\n }\n //========\n // BROWSER\n //========\n else if (typeof window !== 'undefined') {\n window.StateMachine = StateMachine;\n }\n //===========\n // WEB WORKER\n //===========\n else if (typeof self !== 'undefined') {\n self.StateMachine = StateMachine;\n }\n\n}());\n","import type {AnalyticsConfig} from 'bitmovin-player';\n\nimport type {AdapterAPI} from '../../api/AdapterAPI';\nimport {Analytics} from '../../core/Analytics';\nimport type {CustomDataValues} from '../../types/CustomDataValues';\nimport {guardAgainstDuplicatedUserId, sanitizeAnalyticsConfig} from '../../utils/analyticsConfigUtils';\nimport {areCollectorRequirementsValid} from '../../utils/collectorRequirementChecks';\nimport {VERSION} from '../../utils/Version';\n\nimport {BitmovinPwxInternalAdapter} from './BitmovinPwxInternalAdapter';\nimport type {AnalyticsContext} from './Types';\n\nexport class BitmovinPwxAdapter implements AdapterAPI {\n private readonly internalAdapter: BitmovinPwxInternalAdapter;\n private readonly analytics: Analytics;\n\n constructor(context: AnalyticsContext, config: AnalyticsConfig) {\n // no need to check for player augmentation, if analytics has already been initialized on this player instance,\n // because this adapter is created only once with BitmovinPwxAnalyticsPackage\n\n const sanitizedConfig = sanitizeAnalyticsConfig(config);\n if (!areCollectorRequirementsValid(sanitizedConfig)) {\n throw new Error('Failed to create BitmovinPwxAdapter: domain is required');\n }\n\n guardAgainstDuplicatedUserId(sanitizedConfig);\n\n this.internalAdapter = new BitmovinPwxInternalAdapter(context);\n this.analytics = Analytics.create(sanitizedConfig, this.internalAdapter);\n }\n\n dispose() {\n this.internalAdapter.release();\n }\n\n static readonly version: string = VERSION;\n\n get version(): string {\n return VERSION;\n }\n\n getCurrentImpressionId = () => this.analytics.getCurrentImpressionId();\n\n getUserId = () => this.analytics.getUserId();\n\n setCustomData = (values: CustomDataValues) => this.internalAdapter.setCustomData(values);\n\n setCustomDataOnce = (values: CustomDataValues) => this.analytics.setCustomDataOnce(values);\n\n sourceChange = (_config: AnalyticsConfig) => {\n // Every time a source is added, a new instance of analytics package is triggered. So technically there are\n // no source changes. Also, a single player instance can handle infinite amount of sources at once.\n //\n // We are aware, at the moment we are handling it as \"every source = one session\". We will need to do\n // some additional work in the future (once we figure out how this part should work) to handle multiple\n // sources in one session (e.g. ads).\n //\n // What we mean by \"no source changes\", is that you do not have API to change \"current playing\" source\n // to something else. You would need to add new source and remove old one (or keep it). One instance can\n // have infinite amount of sources, each source for us is a new analytics session (for now, in certain cases\n // they should be tied together - e.g. ads)\n //\n // @see https://github.com/bitmovin-engineering/bitmovin-analytics-collector/pull/867#discussion_r1660699646\n\n throw new Error('Method not implemented.');\n };\n}\n","import type {EmptyObject} from '@bitmovin/player-web-x/framework-types/BaseTypes';\nimport type {AnyPackage} from '@bitmovin/player-web-x/framework-types/package-api/PackageApi';\n\nimport {tryJSONStringify} from '../../utils/Utils';\n\nimport {BitmovinPwxAdapter} from './BitmovinPwxAdapter';\nimport {\n BundleExportNames,\n CoreExportNames,\n PlaybackApiEventsPackageExportNames,\n SourceExportNames,\n SourcesApiExportNames,\n} from './ExportNames';\nimport type {AnalyticsContext, CreatePackage} from './Types';\n\n/**\n * Copy&pasted from `@bitmovin/player-web-x` !\n *\n * We need `createPackage` function from util file to create a PWX package, but because `@bitmovin/player-web-x` is not\n * ES5 compliant, we had to copy it here.\n *\n * @see https://github.com/bitmovin-engineering/player-web-phoenix-framework/blob/main/src/package-api/PackageApiUtils.ts#L9\n */\nconst createPackageFn: CreatePackage = (name, onAdd, dependencies) => {\n (onAdd as any)._name = name;\n\n return {\n onAdd,\n dependencies,\n } as unknown as AnyPackage<EmptyObject>;\n};\n\nexport const BitmovinPwxAnalyticsPackage = createPackageFn(\n 'analytics-package',\n (_, baseContext) => {\n /*\n Player Web X analytics package.\n It is being run for every source added - so there is no actual source switching per analytics instance.\n Package is instantiating the adapter, and making sure it is disposed once package is aborted.\n */\n\n const {EventListenerEffectFactory, StateEffectFactory} = baseContext.registry.get(CoreExportNames.CoreEffects);\n const context = baseContext.using(EventListenerEffectFactory, StateEffectFactory) as unknown as AnalyticsContext;\n const logger = context.registry.get(BundleExportNames.Logger);\n const source = context.registry.get(SourceExportNames.SourceState);\n const playerConfig = context.registry.get(BundleExportNames.PlayerConfig);\n const analyticsConfig = playerConfig.analytics ?? {};\n // if the player key is not set in analytics config, use the one from player config\n analyticsConfig.playerKey = analyticsConfig.playerKey ?? playerConfig.key;\n\n logger.log(`Applying analytics config ${tryJSONStringify(analyticsConfig)}`);\n const adapter = new BitmovinPwxAdapter(context, analyticsConfig);\n\n logger.log(`Analytics package initializing for \"${source.url}\"...`);\n\n const listener = () => {\n context.abortSignal.removeEventListener('abort', listener);\n logger.log(`Analytics package disposing for \"${source.url}\"`);\n adapter.dispose();\n };\n\n context.abortSignal.addEventListener('abort', listener);\n },\n [\n BundleExportNames.Logger,\n BundleExportNames.PlayerConfig,\n CoreExportNames.Constants,\n CoreExportNames.CoreEffects,\n CoreExportNames.CoreStateAtoms,\n SourceExportNames.SourceState,\n SourcesApiExportNames.SourceEventBus,\n PlaybackApiEventsPackageExportNames.PlaybackEvent,\n ],\n) as any; // we cast package as any to prevent DTS bundle type merging\n","import {StateMachine} from 'javascript-state-machine';\n\nimport {AnalyticsStateMachine} from '../../analyticsStateMachines/AnalyticsStateMachine';\nimport {\n customStateMachineErrorCallback,\n getAllStatesBut,\n logMissingCallbackWarning,\n logStateMachineTransition,\n on,\n} from '../../analyticsStateMachines/stateMachineUtils';\nimport type {HeartbeatService} from '../../core/HeartbeatService';\nimport {Event, JSM_INITIAL_EVENT} from '../../enums/Event';\nimport type {AnalyticsStateMachineOptions} from '../../types/AnalyticsStateMachineOptions';\nimport type {StateMachineCallbacks} from '../../types/StateMachineCallbacks';\nimport {EventDebugging} from '../../utils/EventDebugging';\nimport {logger} from '../../utils/Logger';\nimport {isNumber} from '../../utils/numberUtils';\nimport {isFunction} from '../../utils/Utils';\n\nexport enum State {\n END = 'END',\n ERROR = 'ERROR',\n PAUSE = 'PAUSE',\n PLAYING = 'PLAYING',\n READY = 'READY',\n SETUP = 'SETUP',\n SOURCE_LOADED = 'SOURCE_LOADED',\n STARTUP = 'STARTUP',\n VIDEOSTART_FAILED = 'VIDEOSTART_FAILED',\n}\n\nexport class BitmovinPwxAnalyticsStateMachine extends AnalyticsStateMachine {\n private enabledDebugging = false;\n private debuggingStates: EventDebugging[] = [];\n\n constructor(\n stateMachineCallbacks: StateMachineCallbacks,\n playingHeartbeatService: HeartbeatService,\n opts: AnalyticsStateMachineOptions,\n ) {\n super(stateMachineCallbacks, playingHeartbeatService, opts);\n }\n\n override createStateMachine(opts: AnalyticsStateMachineOptions): StateMachine {\n return StateMachine.create({\n // custom initial state and custom JSM initial event name\n // initial event is used by JSM for the initial state transition 'none' -> 'SETUP'\n initial: {state: State.SETUP, event: JSM_INITIAL_EVENT},\n error: customStateMachineErrorCallback,\n events: [\n {\n name: Event.SOURCE_LOADED,\n from: [State.SETUP, State.ERROR],\n to: State.READY,\n },\n on(Event.READY).stayIn(State.READY),\n on(Event.PAUSE).stayIn(State.READY),\n on(Event.TIMECHANGED).stayIn(State.READY),\n {name: Event.PLAY, from: State.READY, to: State.STARTUP},\n {name: Event.PLAYING, from: State.READY, to: State.PLAYING},\n\n on(Event.PLAY).stayIn(State.STARTUP),\n on(Event.PLAYING).stayIn(State.STARTUP),\n {name: Event.TIMECHANGED, from: State.STARTUP, to: State.PLAYING},\n on(Event.READY).stayIn(State.STARTUP),\n {name: Event.PAUSE, from: State.STARTUP, to: State.READY},\n\n on(Event.PLAYING).stayIn(State.PLAYING),\n on(Event.TIMECHANGED).stayIn(State.PLAYING),\n\n {name: Event.PAUSE, from: State.PLAYING, to: State.PAUSE},\n on(Event.TIMECHANGED).stayIn(State.PAUSE),\n on(Event.PAUSE).stayIn(State.PAUSE),\n {name: Event.PLAY, from: State.PAUSE, to: State.PLAYING},\n {name: Event.PLAYING, from: State.PAUSE, to: State.PLAYING},\n\n {name: Event.END, from: State.PLAYING, to: State.END},\n {name: Event.END, from: State.PAUSE, to: State.END},\n // when replay is triggered (play button is clicked once video finished),\n // we should start a new session, so we should go to STARTUP state\n {name: Event.PLAYING, from: State.END, to: State.STARTUP},\n\n on(Event.TIMECHANGED).stayIn(State.END),\n on(Event.END).stayIn(State.END),\n\n {name: Event.PLAY, from: State.END, to: State.STARTUP},\n {name: Event.ERROR, from: State.STARTUP, to: State.VIDEOSTART_FAILED},\n {name: Event.ERROR, from: getAllStatesBut([State.STARTUP], State), to: State.ERROR},\n\n {name: Event.UNLOAD, from: getAllStatesBut([State.STARTUP], State), to: State.END},\n {name: Event.UNLOAD, from: [State.STARTUP], to: State.VIDEOSTART_FAILED},\n ],\n\n // Keep callbacks sorted by order in which they are called by JSM library (and after order, sorted by name)\n //\n // Do not use convenience, shortened callbacks\n // - instead of `onEVENT` use `onafterEVENT`\n // - instead of `onSTATE` use `onenterSTATE`\n //\n // see: https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#callbacks\n callbacks: {\n [`onleave${State.PLAYING}`]: () => {\n this.playingHeartbeatService.stopHeartbeat();\n },\n\n onleavestate: (event, from, to, eventTimestamp, eventData) => {\n logStateMachineTransition('LEAVE', event, from, to);\n\n // Skip this JSM callback for JSM initial event\n // This event is fired when the state machine is constructed,\n // to transition us from 'none' to custom initial 'SETUP' state\n if (event === JSM_INITIAL_EVENT) {\n return;\n }\n\n // Skip this JSM callback when an JSM event without a timestamp is called,\n // because it would cause NPE in analytics code (state duration calculation etc.).\n // This probably has happened because the state machine was not used correctly,\n // aka. JSM event was not called via `callEvent` method as it should be!\n if (!eventTimestamp) {\n return;\n }\n\n this.addStatesToLog(event, from, to, eventTimestamp, eventData);\n const stateDuration = eventTimestamp - this.onEnterStateTimestamp;\n const isStartup = from === State.STARTUP && to === State.PLAYING;\n this.maybeSetOrClearVideoStartTimeouts(from, to);\n\n if (isStartup) {\n this.stateMachineCallbacks.startup(stateDuration, State.STARTUP.toLowerCase());\n }\n\n const lowerCaseFrom = String(from).toLowerCase();\n if (event === Event.UNLOAD) {\n this.stateMachineCallbacks.unload(stateDuration, lowerCaseFrom);\n } else if (from === State.SETUP) {\n // Setting Player Startup Time to fixed value of 1ms.\n // We can not get correct Player Startup Time from PWX player, because it does not have an \"onInitialized\" event\n this.stateMachineCallbacks.setup(1, State.SETUP.toLowerCase());\n } else if (event === Event.PAUSE && from === State.STARTUP && to === State.READY) {\n // fired PAUSE event in STARTUP state indicates we are moving back to READY,\n // so we have to clean setTimeout, and we should not call any stateMachineCallbacks\n this.clearVideoStartTimeout();\n } else if (from !== State.ERROR && !isStartup) {\n // Default \"onleavestate\" state machine callback\n //\n // Every time, when we leave a state, we should try to call \"state\" callback,\n // to be able to make \"a cut\" and send analytics sample (if necessary)\n const defaultStateMachineCallbackFn = this.stateMachineCallbacks[lowerCaseFrom];\n if (isFunction(defaultStateMachineCallbackFn)) {\n // a try-catch block to add more resilience against callback errors\n try {\n defaultStateMachineCallbackFn(stateDuration, lowerCaseFrom, eventData);\n } catch (e) {\n logger.error('Exception occurred in State Machine callback ' + lowerCaseFrom, eventData, e);\n }\n } else {\n // if callback is not defined, log a warning to indicate to the developer that\n // - a new callback function needs to be implemented to relay on this default state machine callback\n // - or if no callback is needed, we should\n // - early return from this JSM callback\n // - or add this state to the ignored list\n logMissingCallbackWarning(from, [State.READY]);\n }\n }\n },\n\n [`onenter${State.PLAYING}`]: () => {\n this.playingHeartbeatService.startHeartbeat();\n },\n\n onenterstate: (event, from, to, eventTimestamp, _eventData) => {\n logStateMachineTransition('ENTER', event, from, to);\n\n this.onEnterStateTimestamp = eventTimestamp ?? Date.now();\n // if customer set custom \"start time\" timestamp in AnalyticsStateMachineOptions of adapter constructor,\n // use it and override `onEnterStateTimestamp` during JSM initialization (transition to initial SETUP state)\n if (isNumber(opts.starttime) && event === JSM_INITIAL_EVENT) {\n this.onEnterStateTimestamp = opts.starttime;\n }\n },\n\n [`onafter${Event.ERROR}`]: (_event, _from, _to, _eventTimestamp, eventData) => {\n this.stateMachineCallbacks.error(eventData);\n },\n },\n });\n }\n\n addStatesToLog(\n event: string | undefined,\n from: string | undefined,\n to: string | undefined,\n timestamp: number,\n eventObject: any,\n ) {\n if (this.enabledDebugging) {\n this.debuggingStates.push(new EventDebugging(event, from, to, timestamp, eventObject));\n }\n }\n\n getStates() {\n return this.debuggingStates;\n }\n\n setEnabledDebugging(enabled: boolean) {\n this.enabledDebugging = enabled;\n }\n\n private maybeSetOrClearVideoStartTimeouts(from: string | undefined, to: string | undefined) {\n if (from === State.READY && to === State.STARTUP) {\n this.setVideoStartTimeout();\n } else if (from === State.STARTUP && to === State.PLAYING) {\n this.clearVideoStartTimeout();\n }\n }\n}\n","import type {Analytics} from '../../core/Analytics';\nimport {HeartbeatService} from '../../core/HeartbeatService';\nimport {Event} from '../../enums/Event';\nimport {Player} from '../../enums/Player';\nimport {StreamTypes} from '../../enums/StreamTypes';\nimport {ErrorDetailBackend} from '../../features/errordetails/ErrorDetailBackend';\nimport {ErrorDetailTracking} from '../../features/errordetails/ErrorDetailTracking';\nimport type {Feature} from '../../features/Feature';\nimport type {FeatureConfig} from '../../features/FeatureConfig';\nimport type {AnalyticsStateMachineOptions} from '../../types/AnalyticsStateMachineOptions';\nimport type {FeatureConfigContainer} from '../../types/FeatureConfigContainer';\nimport {normalizeVideoDuration, PlaybackInfo} from '../../types/PlaybackInfo';\nimport {InternalAdapter} from '../internal/InternalAdapter';\nimport type {InternalAdapterAPI} from '../internal/InternalAdapterAPI';\n\nimport {BitmovinPwxAnalyticsStateMachine} from './BitmovinPwxAnalyticsStateMachine';\nimport {\n CoreExportNames,\n PlaybackApiEventsPackageExportNames,\n SourceExportNames,\n SourcesApiExportNames,\n} from './ExportNames';\nimport {AnalyticsContext} from './Types';\n\nconst PWX_ABORT_ERROR_CODE = 1007;\n\nexport class BitmovinPwxInternalAdapter extends InternalAdapter implements InternalAdapterAPI {\n /** Boolean flag to prevent multiple calls of the {@link Event.UNLOAD} event */\n private onBeforeUnLoadEvent = false;\n\n private readonly context: AnalyticsContext;\n\n constructor(context: AnalyticsContext, opts?: AnalyticsStateMachineOptions) {\n super(opts);\n this.context = context;\n const playingHeartbeatService = new HeartbeatService(() => this.currentTime);\n const stateMachine = new BitmovinPwxAnalyticsStateMachine(\n this.stateMachineCallbacks,\n playingHeartbeatService,\n this.opts,\n );\n playingHeartbeatService.setListener(stateMachine);\n this.stateMachine = stateMachine;\n }\n\n private getSource() {\n return this.context.registry.get(SourceExportNames.SourceState);\n }\n\n protected get currentTime(): number {\n return this.getSource().playback.playhead.position;\n }\n\n getAutoPlay(): boolean {\n return this.getSource().config.playback.autoplay;\n }\n\n getCurrentPlaybackInfo(): PlaybackInfo {\n const hls = this.getSource().sourceConfig.resources.filter((v) => v.url.includes('.m3u8'))[0]?.url;\n const dash = this.getSource().sourceConfig.resources.filter((v) => v.url.includes('.mpd'))[0]?.url;\n\n const videoRect = this.getSource().video.element?.getBoundingClientRect();\n const videoWidth = Math.round(videoRect?.width ?? 1);\n const videoHeight = Math.round(videoRect?.height ?? 1);\n\n let streamFormat: StreamTypes | undefined = undefined;\n if (hls) {\n streamFormat = StreamTypes.hls;\n } else if (dash) {\n streamFormat = StreamTypes.dash;\n }\n\n // height, width, codecs and bitrate are fixed until we have quality api\n return {\n ...this.getCommonPlaybackInfo(),\n droppedFrames: 0,\n isMuted: this.getSource().video.element?.muted,\n isLive: this.getSource().stream.type === 'live',\n videoWindowHeight: videoHeight,\n videoWindowWidth: videoWidth,\n videoDuration: normalizeVideoDuration(this.getSource().video.element?.duration),\n videoPlaybackHeight: videoHeight,\n videoPlaybackWidth: videoWidth,\n m3u8Url: hls,\n mpdUrl: dash,\n streamFormat,\n videoCodec: undefined, // not tracked yet\n audioCodec: undefined, // not tracked yet\n videoBitrate: 0, // not tracked yet\n audioBitrate: 0, // not tracked yet\n };\n }\n\n getPlayerName(): string {\n return Player.BITMOVIN_PWX;\n }\n\n getPlayerTech(): string {\n return 'webx:html5';\n }\n\n getPlayerVersion(): string {\n return this.context.registry.get(CoreExportNames.Constants).Version;\n }\n\n initialize(analytics: Analytics): Array<Feature<FeatureConfigContainer, FeatureConfig>> {\n this.registerEventListeners();\n this.registerUnloadEventListeners();\n\n const errorDetailTracking = new ErrorDetailTracking(\n analytics.errorDetailTrackingSettingsProvider,\n new ErrorDetailBackend(analytics.errorDetailTrackingSettingsProvider.collectorConfig),\n [analytics.errorDetailSubscribable],\n undefined,\n );\n\n return [errorDetailTracking];\n }\n\n private registerUnloadEventListeners() {\n let handleCollectorUnload = () => {\n if (!this.onBeforeUnLoadEvent) {\n this.onBeforeUnLoadEvent = true;\n const currentTime = this.context.registry.get(SourceExportNames.SourceState).playback.playhead.position;\n this.eventCallback(Event.UNLOAD, {currentTime});\n }\n this.release();\n };\n handleCollectorUnload = handleCollectorUnload.bind(true);\n\n this.context.abortSignal.addEventListener('abort', handleCollectorUnload);\n this.windowEventTracker.addEventListener('beforeunload', handleCollectorUnload);\n this.windowEventTracker.addEventListener('unload', handleCollectorUnload);\n }\n\n private registerEventListeners() {\n // The context might not be same so a different source event bus is available\n const sourceEventBus = this.context.registry.get(SourcesApiExportNames.SourceEventBus);\n const playbackAtom = this.context.registry.get(SourceExportNames.SourceState).playback;\n const PlaybackEvent = this.context.registry.get(PlaybackApiEventsPackageExportNames.PlaybackEvent);\n\n sourceEventBus.on(PlaybackEvent.Ready, () => {\n this.eventCallback(Event.SOURCE_LOADED, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.Play, () => {\n this.eventCallback(Event.PLAY, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.Playing, () => {\n this.eventCallback(Event.PLAYING, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.Paused, () => {\n this.eventCallback(Event.PAUSE, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.TimeChanged, () => {\n this.eventCallback(Event.TIMECHANGED, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.VideoAttached, () => {\n this.eventCallback(Event.SOURCE_LOADED, {currentTime: playbackAtom.playhead.position});\n });\n\n sourceEventBus.on(PlaybackEvent.Ended, () => {\n this.eventCallback(Event.END, {currentTime: playbackAtom.playhead.position});\n });\n\n const abortListener = () => {\n const abortSignalReason = this.context.abortSignal.reason;\n if (abortSignalReason.name === 'SourceRemovedError' || abortSignalReason.name === 'FrameworkDisposedError') {\n this.eventCallback(Event.SOURCE_UNLOADED, {currentTime: playbackAtom.playhead.position});\n } else {\n this.eventCallback(Event.ERROR, {\n currentTime: playbackAtom.playhead.position,\n code: PWX_ABORT_ERROR_CODE,\n message: abortSignalReason.message,\n data: abortSignalReason,\n originalError: abortSignalReason,\n });\n }\n\n this.context.abortSignal.removeEventListener('abort', abortListener);\n };\n\n this.context.abortSignal.addEventListener('abort', abortListener);\n }\n}\n","/*!\n * This file was created to provide Bitmovin Player Web X \"export names\" as constants,\n * because they are exported as enums in 'd.ts' files, that we can't import as value in this project.\n *\n * Once `@bitmovin/player-web-x` bundle will provide these enums in way we could import them, we could remove/simplify this file.\n */\n\nimport type {BundleExportNames as BundleExportNamesEnum} from '@bitmovin/player-web-x/types/bundles/Types';\nimport type {CoreExportNames as CoreExportNamesEnum} from '@bitmovin/player-web-x/types/packages/core/Types';\nimport type {PlaybackApiEventsPackageExportNames as PlaybackApiEventsPackageExportNamesEnum} from '@bitmovin/player-web-x/types/packages/playback-api/playback-api-events/Types';\nimport type {SourceExportNames as SourceExportNamesEnum} from '@bitmovin/player-web-x/types/packages/source/Types';\nimport type {SourcesApiExportNames as SourcesApiExportNameEnum} from '@bitmovin/player-web-x/types/packages/sources-api/Types';\n\nimport type {EnumAsUnion} from '../../utils/EnumAsUnion';\n\nconst BundleExportNamesLogger: EnumAsUnion<typeof BundleExportNamesEnum> = 'logger';\nconst BundleExportNamesPlayerConfig: EnumAsUnion<typeof BundleExportNamesEnum> = 'player-config';\nexport const BundleExportNames = {\n Logger: BundleExportNamesLogger,\n PlayerConfig: BundleExportNamesPlayerConfig,\n};\n\nconst CoreExportNamesUtils: EnumAsUnion<typeof CoreExportNamesEnum> = 'utils';\nconst CoreExportNamesConstants: EnumAsUnion<typeof CoreExportNamesEnum> = 'constants';\nconst CoreExportNamesCoreEffects: EnumAsUnion<typeof CoreExportNamesEnum> = 'core-effects';\nconst CoreExportNamesCoreStateAtoms: EnumAsUnion<typeof CoreExportNamesEnum> = 'core-state-atoms';\nexport const CoreExportNames = {\n Utils: CoreExportNamesUtils,\n Constants: CoreExportNamesConstants,\n CoreEffects: CoreExportNamesCoreEffects,\n CoreStateAtoms: CoreExportNamesCoreStateAtoms,\n} as const;\n\nconst PlaybackApiEventsPackageExportNamesPlaybackEvent: EnumAsUnion<typeof PlaybackApiEventsPackageExportNamesEnum> =\n 'playback-event';\nexport const PlaybackApiEventsPackageExportNames = {\n PlaybackEvent: PlaybackApiEventsPackageExportNamesPlaybackEvent,\n} as const;\n\nconst SourceExportNamesCreateSourceStateAtom: EnumAsUnion<typeof SourceExportNamesEnum> = 'create-source-state-atom';\nconst SourceExportNamesCreateSourceReference: EnumAsUnion<typeof SourceExportNamesEnum> = 'create-source-reference';\nconst SourceExportNamesSourceReferences: EnumAsUnion<typeof SourceExportNamesEnum> = 'source-references';\nconst SourceExportNamesSourceState: EnumAsUnion<typeof SourceExportNamesEnum> = 'source-state-atom';\nexport const SourceExportNames = {\n CreateSourceStateAtom: SourceExportNamesCreateSourceStateAtom,\n CreateSourceReference: SourceExportNamesCreateSourceReference,\n SourceReferences: SourceExportNamesSourceReferences,\n SourceState: SourceExportNamesSourceState,\n} as const;\n\nconst SourcesApiExportNamesSourceApiManager: EnumAsUnion<typeof SourcesApiExportNameEnum> = 'source-api-manager';\nconst SourcesApiExportNamesVideoElementUtils: EnumAsUnion<typeof SourcesApiExportNameEnum> = 'video-element-utils';\nconst SourcesApiExportNamesSourceEventBus: EnumAsUnion<typeof SourcesApiExportNameEnum> = 'source-event-bus';\nexport const SourcesApiExportNames = {\n SourceApiManager: SourcesApiExportNamesSourceApiManager,\n VideoElementUtils: SourcesApiExportNamesVideoElementUtils,\n SourceEventBus: SourcesApiExportNamesSourceEventBus,\n} as const;\n","import {AnalyticsStateMachine} from '../../analyticsStateMachines/AnalyticsStateMachine';\nimport {EventDispatcher} from '../../core/EventDispatcher';\nimport QualityChangeService from '../../core/QualityChangeService';\nimport {SourceInfoFallbackService} from '../../core/SourceInfoFallbackService';\nimport {SsaiService} from '../../core/ssai/SsaiService';\nimport {Event, EventMap} from '../../enums/Event';\nimport {AnalyticsConfig} from '../../types/AnalyticsConfig';\nimport {AnalyticsStateMachineOptions} from '../../types/AnalyticsStateMachineOptions';\nimport {CustomDataValues} from '../../types/CustomDataValues';\nimport {DownloadSpeedInfo} from '../../types/DownloadSpeedInfo';\nimport {DrmPerformanceInfo} from '../../types/DrmPerformanceInfo';\nimport type {CustomDataValuesEvent} from '../../types/EventData';\nimport {NoExtraProperties} from '../../types/NoExtraProperties';\nimport {SegmentInfo} from '../../types/SegmentInfo';\nimport type {SourceMetadata} from '../../types/SourceMetadata';\nimport {defaultStateMachineCallbacks, StateMachineCallbacks} from '../../types/StateMachineCallbacks';\nimport {getGlobalScreenDimensions} from '../../utils/globalScopeUtils';\nimport {logger} from '../../utils/Logger';\nimport {getCurrentTimestamp} from '../../utils/Utils';\nimport {WindowEventTracker} from '../../utils/WindowEventTracker';\n\nimport {EventCallbackDispatcher} from './EventCallbackDispatcher';\n\nexport abstract class InternalAdapter implements EventCallbackDispatcher {\n readonly onLicenseKeyReceived: EventDispatcher<{licenseKey: string}> = new EventDispatcher();\n readonly onLicenseCallFailed: EventDispatcher<any> = new EventDispatcher();\n readonly qualityChangeService: QualityChangeService = new QualityChangeService();\n readonly ssaiService = new SsaiService();\n readonly stateMachineCallbacks: StateMachineCallbacks = {...defaultStateMachineCallbacks};\n\n protected stateMachine!: AnalyticsStateMachine;\n protected opts: AnalyticsStateMachineOptions;\n protected sourceInfoFallbackService: SourceInfoFallbackService = new SourceInfoFallbackService();\n protected drmPerformanceInfo: DrmPerformanceInfo | undefined = undefined;\n protected readonly windowEventTracker: WindowEventTracker = new WindowEventTracker();\n\n protected abstract get currentTime(): number;\n\n constructor(opts?: AnalyticsStateMachineOptions) {\n if (!opts) {\n opts = {\n starttime: undefined,\n };\n }\n if (!opts.starttime) {\n opts.starttime = getCurrentTimestamp();\n }\n\n this.opts = opts;\n }\n\n release() {\n this.stateMachine.resetIntervals();\n this.stateMachineCallbacks.release();\n this.resetSourceRelatedState();\n this.windowEventTracker.release();\n }\n\n eventCallback<StateMachineEvent extends keyof EventMap, StateMachineEventData extends EventMap[StateMachineEvent]>(\n event: StateMachineEvent,\n eventData: NoExtraProperties<EventMap[StateMachineEvent], StateMachineEventData>,\n eventTimestamp: number = Date.now(),\n ) {\n eventData = eventData || {};\n if (!this.stateMachine) {\n logger.log(\"Bitmovin Analytics: StateMachine isn't ready yet\");\n } else {\n this.stateMachine.callEvent(event, eventData, eventTimestamp);\n }\n }\n\n getCommonPlaybackInfo() {\n const dimensions = getGlobalScreenDimensions();\n\n return {\n screenHeight: dimensions?.height,\n screenWidth: dimensions?.width,\n };\n }\n\n getDrmPerformanceInfo(): DrmPerformanceInfo | undefined {\n return undefined;\n }\n\n getSegmentInfo(): SegmentInfo[] {\n return [];\n }\n\n getDownloadSpeedInfo(): DownloadSpeedInfo {\n return {\n segmentsDownloadCount: 0,\n segmentsDownloadSize: 0,\n segmentsDownloadTime: 0,\n avgDownloadSpeed: 0,\n minDownloadSpeed: 0,\n maxDownloadSpeed: 0,\n avgTimeToFirstByte: 0,\n };\n }\n\n resetDownloadSpeedInfoMeasures(): void {\n // noop by default\n }\n\n setCustomData(values: CustomDataValues) {\n const previousState = this.stateMachine.currentState;\n const eventData: CustomDataValuesEvent = {customDataValues: values, currentTime: this.currentTime};\n\n if (\n this.stateMachine.currentState &&\n (this.stateMachine.currentState === 'PAUSE' || this.stateMachine.currentState === 'PLAYING')\n ) {\n // If we are in State.PAUSE or State.PLAYING, we want to make \"a cut\" of the current state\n // to trigger sample sending with current custom data values.\n this.eventCallback(Event.CUSTOM_DATA_CHANGE, {currentTime: this.currentTime});\n // Then we have to call this \"previous state\" event to return back\n // to the previous state and to set new custom data values.\n // !! here we relay on the fact that we have `PAUSE` and `PLAYING` events with the same name as the states above !!\n this.eventCallback(Event[previousState], eventData);\n }\n // ... else, for any other states, we don't care, and we will just set new custom data values asap, so they will\n // be sent with the upcoming sample\n else {\n this.stateMachineCallbacks.customdatachange(undefined, undefined, eventData);\n }\n }\n\n sourceChange(analyticsConfig: AnalyticsConfig): void {\n this.eventCallback(Event.MANUAL_SOURCE_CHANGE, {currentTime: this.currentTime, config: analyticsConfig});\n }\n\n resetSourceRelatedState(): void {\n this.sourceInfoFallbackService.reset();\n this.drmPerformanceInfo = undefined;\n }\n\n programChange(sourceMetadata: SourceMetadata): void {\n const isSsaiActive = this.ssaiService.isInActiveState();\n this.stateMachine.programChange(this.currentTime, isSsaiActive, sourceMetadata);\n }\n}\n","import {AdBreakInfo} from '../../../types/ads/AdBreakInfo';\nimport {AdInfo} from '../../../types/ads/AdInfo';\n\nexport class AdCallbacks {\n onAdStarted = (_ad: AdInfo): void => undefined;\n onAdFinished = (_ad: AdInfo): void => undefined;\n onAdBreakStarted = (_adBreak: AdBreakInfo): void => undefined;\n onAdBreakFinished = (_adBreak: AdBreakInfo): void => undefined;\n onAdClicked = (_event: AdClickedPayload): void => undefined;\n onAdError = (_event: AdErrorPayload): void => undefined;\n onAdManifestLoaded = (_event: AdManifestLoadedPayload): void => undefined;\n onAdQuartile = (_event: AdQuartilePayload): void => undefined;\n onAdSkipped = (_ad: AdInfo): void => undefined;\n onPlay = (): void => undefined;\n onPause = (): void => undefined;\n onBeforeUnload = (): void => undefined;\n}\n\nexport interface AdModuleAPI {\n readonly adCallbacks: AdCallbacks;\n isLinearAdActive: () => boolean;\n getContainer: () => HTMLElement | undefined;\n getAdModuleInfo: () => {name?: string; version?: string};\n currentTime: () => number;\n getAutoPlay(): boolean;\n}\n\nexport interface AdClickedPayload {\n clickThroughUrl?: string;\n}\n\nexport interface AdErrorPayload {\n code?: number;\n message?: string;\n adBreakInfo?: AdBreakInfo;\n activeAdId?: string;\n}\n\nexport interface AdManifestLoadedPayload {\n adBreakInfo?: AdBreakInfo;\n manifestDownloadTime?: number;\n isVmap: boolean;\n}\n\nexport enum AdQuartile {\n FIRST_QUARTILE = 'firstQuartile',\n MIDPOINT = 'midpoint',\n THIRD_QUARTILE = 'thirdQuartile',\n}\n\nexport interface AdQuartilePayload {\n quartile: AdQuartile;\n}\n","import type {HeartbeatListener} from '../core/HeartbeatService';\nimport {HeartbeatService} from '../core/HeartbeatService';\nimport {SSAI_RELATED_SAMPLE_MARKER} from '../core/ssai/ssaiUtils';\nimport {ErrorCode} from '../enums/ErrorCode';\nimport {Event, EventMap} from '../enums/Event';\nimport type {AnalyticsStateMachineOptions} from '../types/AnalyticsStateMachineOptions';\nimport type {NoExtraProperties} from '../types/NoExtraProperties';\nimport type {SourceMetadata} from '../types/SourceMetadata';\nimport {HeartbeatPayload, StateMachineCallbacks} from '../types/StateMachineCallbacks';\nimport {logger} from '../utils/Logger';\nimport * as Settings from '../utils/Settings';\nimport * as Utils from '../utils/Utils';\nimport {isNotNullish} from '../utils/Utils';\n\nconst REBUFFERING_HEARTBEAT_INTERVALS = [3000, 5000, 10000, 30000, 59700];\n\nexport abstract class AnalyticsStateMachine implements HeartbeatListener {\n protected stateMachine: StateMachine.StateMachine & {[key: string]: any};\n protected onEnterStateTimestamp = 0;\n\n protected readonly videoStartupTimeoutMs: number = Settings.ANALYTICS_VIDEOSTART_TIMEOUT;\n protected readonly rebufferTimeoutMs: number = Settings.ANALYTICS_REBUFFER_TIMEOUT;\n protected readonly playingHeartbeatService: HeartbeatService;\n\n private rebufferingHeartbeatIntervalHandle?: ReturnType<typeof setInterval>;\n private currentRebufferingIntervalIndex = 0;\n private rebufferingTimeoutHandle?: ReturnType<typeof setTimeout>;\n private videoStartTimeout?: ReturnType<typeof setTimeout>;\n\n constructor(\n protected stateMachineCallbacks: StateMachineCallbacks,\n playingHeartbeatService: HeartbeatService,\n opts: AnalyticsStateMachineOptions,\n ) {\n this.stateMachine = this.createStateMachine(opts);\n this.playingHeartbeatService = playingHeartbeatService;\n }\n\n abstract createStateMachine(opts: AnalyticsStateMachineOptions): StateMachine.StateMachine;\n\n callEvent<StateMachineEvent extends keyof EventMap, StateMachineEventData extends EventMap[StateMachineEvent]>(\n event: StateMachineEvent,\n eventData: NoExtraProperties<EventMap[StateMachineEvent], StateMachineEventData>,\n eventTimestamp: number,\n ): void {\n const stateMachineEventMethod = this.stateMachine[event];\n\n if (stateMachineEventMethod == null) {\n // If the event (aka. the event method) is not defined in the JSM, we log a warning,\n // because it means that we are explicitly trying to call that JSM event from our code (probably adapter),\n // but it was not defined in the JSM at all. Either we are missing it or it should not be called at all!\n logger.warn(`StateMachine ignored event \"${event}\" call, because it was not defined`, eventData, eventTimestamp);\n return;\n }\n\n try {\n // By default, if you try to call an event method not allowed in the current state, the state machine will throw an exception.\n // see: https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#handling-failures\n //\n // This JSM library behavior can be changed by providing \"a custom error handler\" in the `create()`\n // method of the state machine, and we do that in every state machine!\n //\n // But we still want to have here a try-catch block, in case of unexpected state machine code,\n // to avoid propagating the exception to the rest of the application (and breaking customer app).\n stateMachineEventMethod.call(this.stateMachine, eventTimestamp, eventData);\n } catch (e) {\n logger.error(\n `StateMachine ignored event \"${event}\" call, because it has thrown exception in the current state \"${this.currentState}\"`,\n eventData,\n eventTimestamp,\n e,\n );\n }\n }\n\n get currentState(): string {\n return this.stateMachine.current;\n }\n\n resetIntervals() {\n this.clearVideoStartTimeout();\n this.clearRebufferingTimeoutHandle(true);\n this.clearRebufferingHeartbeatHandle();\n }\n\n //#region rebuffer timeout\n\n protected startRebufferingHeartbeatInterval(reset = true) {\n this.resetRebufferingHelpers(reset);\n\n this.startRebufferingTimeoutHandle();\n\n this.rebufferingHeartbeatIntervalHandle = setInterval(() => {\n const state = this.stateMachine.current.toLowerCase();\n if (state !== 'rebuffering') {\n this.resetRebufferingHelpers();\n return;\n }\n const timestamp = new Date().getTime();\n const stateDuration = timestamp - this.onEnterStateTimestamp;\n this.stateMachineCallbacks.heartbeat(stateDuration, state, {buffered: stateDuration});\n this.onEnterStateTimestamp = timestamp;\n this.currentRebufferingIntervalIndex = Math.min(\n this.currentRebufferingIntervalIndex + 1,\n REBUFFERING_HEARTBEAT_INTERVALS.length - 1,\n );\n this.startRebufferingHeartbeatInterval(false);\n }, REBUFFERING_HEARTBEAT_INTERVALS[this.currentRebufferingIntervalIndex]);\n }\n\n protected resetRebufferingHelpers(reset = true) {\n if (reset) {\n this.currentRebufferingIntervalIndex = 0;\n }\n this.clearRebufferingHeartbeatHandle();\n this.clearRebufferingTimeoutHandle(reset);\n }\n\n protected clearRebufferingHeartbeatHandle() {\n if (isNotNullish(this.rebufferingHeartbeatIntervalHandle)) {\n clearInterval(this.rebufferingHeartbeatIntervalHandle);\n this.rebufferingHeartbeatIntervalHandle = undefined;\n }\n }\n\n private startRebufferingTimeoutHandle() {\n if (this.currentRebufferingIntervalIndex > 0) {\n return;\n }\n this.rebufferingTimeoutHandle = setTimeout(() => {\n this.callEvent(\n Event.ERROR,\n {\n ...ErrorCode.BUFFERING_TIMEOUT_REACHED,\n data: {\n additionalData: `StateMachine timed out after ${this.rebufferTimeoutMs} ms of consecutive buffering.`,\n },\n },\n Utils.getCurrentTimestamp(),\n );\n this.stateMachineCallbacks.release();\n }, this.rebufferTimeoutMs);\n }\n\n protected clearRebufferingTimeoutHandle(reset: boolean) {\n if (reset && isNotNullish(this.rebufferingTimeoutHandle)) {\n clearTimeout(this.rebufferingTimeoutHandle);\n this.rebufferingTimeoutHandle = undefined;\n }\n }\n //#endregion\n\n //#region videoStartupFailed\n protected setVideoStartTimeout() {\n if (isNotNullish(this.videoStartTimeout)) {\n this.clearVideoStartTimeout();\n }\n this.videoStartTimeout = setTimeout(() => {\n this.callEvent(Event.VIDEOSTART_TIMEOUT, {}, Date.now());\n this.stateMachineCallbacks.release();\n }, this.videoStartupTimeoutMs);\n }\n\n protected clearVideoStartTimeout() {\n clearTimeout(this.videoStartTimeout);\n this.videoStartTimeout = undefined;\n }\n //#endregion\n\n onHeartbeat(playerCurrentTime: number): void {\n this.sendPlayingSample(Date.now(), playerCurrentTime);\n }\n\n /**\n * Should be used in the \"PLAYING\" state only, and only by \"SSAI\", \"ProgramChange\" and \"Playing Heartbeat\" features,\n * otherwise it will log a warning and do nothing!\n *\n * It calls the {@link StateMachineCallbacks.heartbeat} callback, to send out the current playing sample (it cuts\n * current PLAYING state) and resets time measurements to set a new start of PLAYING state again with new timestamp\n * and video time. So the next sample will be sent with the duration from the last cut.\n *\n * We have chosen to use {@link StateMachineCallbacks.heartbeat} callback here, because it was the easiest and the\n * fastest way to trigger 'playing' sample sending (with additional properties like \"ssai marker\"), without changing\n * and refactoring too much code, in future this code should be refactored with better naming.\n *\n * @param timestamp current timestamp\n * @param playerCurrentTime the current player playback time of the video in seconds\n * @param triggeredBySsai boolean to mark the sample as SSAI triggered\n * @param triggeredByProgramChange boolean to mark the sample as ProgramChange triggered\n */\n sendPlayingSample(\n timestamp: number,\n playerCurrentTime: number,\n triggeredBySsai = false,\n triggeredByProgramChange = false,\n ) {\n const state = this.stateMachine.current.toLowerCase();\n // We don't allow this in any other state because it could interrupt the natural flow of the states.\n // Only PLAYING is considered a state which we can interrupt/cut by heartbeat or SSAI interaction.\n if (state !== 'playing') {\n // our logic for \"SSAI\" and \"playing heartbeat\" is built on the assumption that we send only 'playing' samples,\n // but that \"if\" restriction is spread across the codebase, so we need to log a warning here, to see a potential\n // problems in our logic, if reported by from customer and report will contain these logs\n logger.warn(`Unexpected call of \"sendPlayingSample\" in AnalyticsStateMachine from \"${state}\" state`);\n return;\n }\n\n this.stateMachineCallbacks.setVideoTimeEndFromEvent({currentTime: playerCurrentTime});\n\n const stateDuration = timestamp - this.onEnterStateTimestamp;\n const payload: HeartbeatPayload = {\n played: stateDuration,\n isProgramChange: triggeredByProgramChange ? true : undefined,\n };\n\n if (triggeredBySsai) {\n payload[SSAI_RELATED_SAMPLE_MARKER] = true;\n }\n\n this.stateMachineCallbacks.heartbeat(stateDuration, state, payload);\n\n this.resetCurrentStateStart(timestamp, playerCurrentTime);\n }\n\n private resetCurrentStateStart(stateEnterTimestamp: number, playerCurrentTime: number): void {\n this.onEnterStateTimestamp = stateEnterTimestamp;\n this.stateMachineCallbacks.setVideoTimeStartFromEvent({currentTime: playerCurrentTime});\n }\n\n programChange(playerCurrentTime: number, isSsaiActive: boolean, sourceMetadata: SourceMetadata): void {\n // if program change happens before or during STARTUP (or other \"startup state\", like bitmovin8 STARTUP_AUTOPLAY),\n // we don't want to do any \"cut\", because it has not started yet, we just want to update source metadata\n // and wait for the natural start\n if (\n this.stateMachine.current === 'SETUP' ||\n this.stateMachine.current === 'READY' ||\n this.stateMachine.current === 'STARTUP' ||\n this.stateMachine.current === 'STARTUP_AUTOPLAY'\n ) {\n this.stateMachineCallbacks.updateSourceMetadata(sourceMetadata);\n return;\n }\n\n const programChangeTimestamp = Date.now();\n\n // If the program change happens during PLAYING state, we want to \"cut it\" and send asap last playing sample\n // of the previous program (session) with the duration from the start of PLAYING state to the program change\n if (this.stateMachine.current === 'PLAYING') {\n this.sendPlayingSample(programChangeTimestamp, playerCurrentTime, isSsaiActive, true);\n }\n // ... else in any other state, we just want to reset time measurements to set a new start of the current state\n else {\n this.resetCurrentStateStart(programChangeTimestamp, playerCurrentTime);\n }\n\n this.stateMachineCallbacks.programChange(sourceMetadata);\n }\n}\n","import {\n StateMachineErrorCallback,\n Error as StateMachineErrorCode,\n StateMachineEventDef,\n} from 'javascript-state-machine';\n\nimport {logger, padRight} from '../utils/Logger';\nimport {objectValues} from '../utils/objectUtils';\nimport {isNullish, tryJSONStringify} from '../utils/Utils';\n\n/**\n * @deprecated use {@link whileIn} instead, to switch mindset and think about allowed events in the current state\n * instead of thinking of current event and its allowed states. Because as analytics we focus mostly on reporting\n * states or states changes.\n */\nexport const on = (event: string): {stayIn: (state: string) => StateMachineEventDef} => ({\n stayIn: (state: string) => ({name: event, from: state, to: state}),\n});\n\ntype EventsToStateMachineEventDefFn = (...events: string[]) => StateMachineEventDef[];\ntype WhileInReturnType = {\n /**\n * Create {@link StateMachineEventDef} from event(s) to be used in the state machine definition, but ONLY to indicate\n * that we want to only pass event(s) over, to avoid a log message of ignored event in the current state from\n * the state machine.\n *\n * @remarks\n *\n * If we decide in the future to ignore {@link StateMachineErrorCode.INVALID_TRANSITION} logs created in\n * {@link customStateMachineErrorCallback}, this method and JSM event definitions created with could be removed\n * from source code. Until then, we use it to make code more readable.\n */\n passOver: EventsToStateMachineEventDefFn;\n\n /**\n * Same as {@link passOver}, but used in rare cases, when it indicates that we expect the event(s) to occur\n * in the current state, aka. we want to trigger the state machine event callbacks for these event(s),\n * even if we stay in the same state.\n *\n * @remarks\n *\n * If we don't expect the event while staying in the current state, we don't expect state machine event callbacks\n * to run, we should use {@link passOver} instead!\n */\n runEventCallbacksFor: EventsToStateMachineEventDefFn;\n};\n\n/**\n * This utility is here to help us write more readable code and let us define allowed/expected events in the current state.\n *\n * ### Example:\n *\n * Instead of writing:\n *\n * ```typescript\n * {name: Event.PAUSE, from: State.END, to: State.END},\n * {name: Event.SEEK, from: State.END, to: State.END},\n * {name: Event.SEEKED, from: State.END, to: State.END},\n * {name: Event.TIMECHANGED, from: State.END, to: State.END},\n * ```\n *\n * we can write:\n *\n * ```typescript\n * ...whileIn(State.END).passOver(Event.PAUSE, Event.SEEK, Event.SEEKED, Event.TIMECHANGED),\n * // OR when we expect and react on that event occurrence:\n * ...whileIn(State.END).runEventCallbacksFor(Event.PAUSE, Event.SEEK, Event.SEEKED, Event.TIMECHANGED),\n * ```\n *\n * @see customStateMachineErrorCallback\n * @see https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#handling-failures\n */\nexport const whileIn = (state: string): WhileInReturnType => {\n const stateMachineEventDefBuilderFn = (...events: string[]) =>\n events.map((event) => ({name: event, from: state, to: state}));\n return {runEventCallbacksFor: stateMachineEventDefBuilderFn, passOver: stateMachineEventDefBuilderFn};\n};\n\n/**\n * By default, if you try to call an event method not allowed in the current state,\n * the state machine will throw an exception (not allow it).\n *\n * This JSM library behavior can be changed by providing \"a custom error handler\" in the `create()`\n * method of the state machine, and we do that in every state machine!\n *\n * This way we make code more resilient to errors, because we do not throw errors from JSM event methods,\n * but instead we handle them here and just log them with {@link logger}.\n *\n * @see https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#handling-failures\n */\nexport const customStateMachineErrorCallback: StateMachineErrorCallback = (\n eventName,\n from,\n to,\n args,\n errorCode,\n errorMessage,\n _ex,\n) => {\n const loggerMessage = `StateMachine ignored event \"${eventName}\", ${errorMessage}`;\n const loggerMessageData = {\n eventName,\n from,\n to,\n args: tryJSONStringify(args),\n errorCode,\n errorMessage,\n };\n\n // if caller tried to fire an event that was inappropriate in the current state\n if (errorCode === StateMachineErrorCode.INVALID_TRANSITION) {\n // The event itself is defined in JSM (in some other StateMachineEventDef). However, it is just not considered to\n // be appropriate in the current state.\n //\n // We should log it as a simple log. It is not an error nor a warning,\n // - because JSM will just stay in the same JSM state (and that can be considered as expected behavior)\n // - BUT it will NOT trigger JSM event callbacks like `onafterEVENT`, on `onbeforeEVENT`!\n logger.log(loggerMessage, loggerMessageData);\n return;\n }\n\n logger.error(loggerMessage, loggerMessageData);\n};\n\n/**\n * Log warning messages with {@link logger} about missing StateMachine callback,\n * if the state is not nullish and does not match any of the ignored states.\n */\nexport const logMissingCallbackWarning = (state: string | undefined, ignoreStates: string[] = []) => {\n if (isNullish(state)) {\n return;\n }\n\n const shouldReportMissingCallback = isNullish(ignoreStates.find((ignoredState) => state === ignoredState));\n if (shouldReportMissingCallback) {\n logger.warn('Could not find StateMachine callback function for ' + state);\n }\n};\n\n/** Log message with {@link logger} about StateMachine ENTER/LEAVE transition */\nexport const logStateMachineTransition = (\n transition: 'ENTER' | 'LEAVE',\n event: string | undefined,\n from: string | undefined,\n to: string | undefined,\n) => {\n if (transition === 'ENTER') {\n logger.log(`[ENTER] ${padRight(to, 20)} EVENT: ${padRight(event, 20)} from ${padRight(from, 20)}`);\n } else {\n logger.log(`[LEAVE] ${padRight(from, 20)} EVENT: ${padRight(event, 20)} to ${padRight(to, 20)}`);\n }\n};\n\n/**\n * Return all values/states of the given state string enum.\n *\n * @param stateStringEnumObj\n *\n * @remarks\n *\n * We cannot directly check at if an object is a TypeScript string enum, because enums are erased at compile time and\n * become plain objects in JavaScript. However, you can heuristically check if an object looks like a string enum\n * by verifying that all its values are strings. This checks if all values of the object are strings, which is typical\n * for a string enum. However, this is not a foolproof check, just a heuristic.\n */\nexport function getAllStates<T extends {[key: string]: string}>(stateStringEnumObj: T): Array<T[keyof T]> {\n return objectValues(stateStringEnumObj) as Array<T[keyof T]>;\n}\n\nexport function getAllStatesBut<T extends {[key: string]: string}>(\n excludedStates: Array<T[keyof T]>,\n stateEnumObj: T,\n): Array<T[keyof T]> {\n return getAllStates(stateEnumObj).filter((s) => excludedStates.indexOf(s) < 0);\n}\n","import {\n AdClickedPayload,\n AdErrorPayload,\n AdManifestLoadedPayload,\n AdModuleAPI,\n AdQuartile,\n AdQuartilePayload,\n} from '../adapters/internal/ads/AdModuleAPI';\nimport {AdBreakInfo} from '../types/ads/AdBreakInfo';\nimport {AdInfo} from '../types/ads/AdInfo';\nimport type {AdSample} from '../types/AdSample';\nimport {logger} from '../utils/Logger';\nimport {isFiniteNumber} from '../utils/numberUtils';\nimport {buildAdSample} from '../utils/sampleUtils';\nimport * as Utils from '../utils/Utils';\nimport {isNotNullish, isNullish, tryJSONStringify} from '../utils/Utils';\nimport {generateUUID} from '../utils/uuidUtils';\nimport {VERSION} from '../utils/Version';\nimport {ViewportTracker} from '../utils/ViewportTracker';\n\nimport {Analytics} from './Analytics';\n\nexport class AdAnalytics {\n static readonly MODULE_NAME = 'ads';\n private static readonly TIMEOUT_CURRENT_TIME_INTERVAL = 100;\n\n /** Boolean flag to prevent multiple calls of the {@link Event.UNLOAD} event */\n private onBeforeUnLoadEvent = false;\n private analytics: Analytics;\n private adapter: AdModuleAPI;\n private viewportTracker?: ViewportTracker;\n\n private activeAdBreakState: ActiveAdBreakState | undefined;\n private activeAdState: ActiveAdState | undefined;\n\n private adManifestDownloadTime: number | undefined;\n private adStartupTimestamp?: number;\n private beginPlayingTimestamp?: number;\n private enterViewportTimestamp?: number;\n private isPlaying = false;\n private currentTime?: number;\n private currentTimeInterval?: ReturnType<typeof setInterval>;\n private adPodPosition = 0;\n\n constructor(analytics: Analytics, adapter: AdModuleAPI) {\n this.analytics = analytics;\n this.adapter = adapter;\n\n this.adapter.adCallbacks.onAdStarted = (event) => this.onAdStarted(event);\n this.adapter.adCallbacks.onAdFinished = (event) => this.onAdFinished(event);\n this.adapter.adCallbacks.onAdBreakStarted = (event) => this.onAdBreakStarted(event);\n this.adapter.adCallbacks.onAdBreakFinished = (event) => this.onAdBreakFinished(event);\n this.adapter.adCallbacks.onAdClicked = (event) => this.onAdClicked(event);\n this.adapter.adCallbacks.onAdError = (event) => this.onAdError(event);\n this.adapter.adCallbacks.onAdManifestLoaded = (event) => this.onAdManifestLoaded(event);\n this.adapter.adCallbacks.onPlay = () => this.onPlay();\n this.adapter.adCallbacks.onPause = () => this.onPause();\n this.adapter.adCallbacks.onBeforeUnload = () => this.onBeforeUnload();\n this.adapter.adCallbacks.onAdSkipped = (event) => this.onAdSkipped(event);\n this.adapter.adCallbacks.onAdQuartile = (event) => this.onAdQuartile(event);\n\n const container = this.adapter.getContainer();\n if (isNotNullish(container)) {\n this.viewportTracker = new ViewportTracker(container, () => this.onIntersectionChanged(), 0.5);\n }\n }\n\n release() {\n this.clearCurrentTimeInterval();\n this.viewportTracker?.dispose();\n this.adManifestDownloadTime = undefined;\n }\n\n onIntersectionChanged() {\n if (!this.activeAdState) {\n return;\n }\n if (this.isContainerInViewport()) {\n this.enterViewportTimestamp = Date.now();\n } else {\n if (this.enterViewportTimestamp) {\n this.activeAdState.timeInViewport =\n (this.activeAdState.timeInViewport || 0) + Date.now() - this.enterViewportTimestamp;\n }\n }\n }\n\n isContainerInViewport(): boolean {\n return this.viewportTracker ? this.viewportTracker.isInViewport() : true;\n }\n\n onPlay() {\n if (this.adapter && this.adapter.isLinearAdActive() && this.activeAdState) {\n const timestamp = Date.now();\n this.beginPlayingTimestamp = timestamp;\n this.enterViewportTimestamp = timestamp;\n this.isPlaying = true;\n }\n }\n\n onPause() {\n if (this.adapter && this.adapter.isLinearAdActive() && this.activeAdState) {\n this.updatePlayingTime(this.activeAdState);\n this.isPlaying = false;\n }\n }\n\n onAdManifestLoaded(payload: AdManifestLoadedPayload) {\n if (payload.isVmap) {\n this.sendAnalyticsRequest(buildInitialActiveAdBreakState(payload.adBreakInfo));\n return;\n }\n\n this.adManifestDownloadTime = payload.manifestDownloadTime;\n }\n\n onAdBreakStarted(adBreak: AdBreakInfo) {\n this.adPodPosition = 0;\n this.activeAdBreakState = buildInitialActiveAdBreakState({\n ...adBreak,\n manifestDownloadTime: this.adManifestDownloadTime,\n });\n delete this.adManifestDownloadTime;\n this.adStartupTimestamp = Date.now();\n }\n\n onAdBreakFinished(_adBreak: AdBreakInfo) {\n this.resetActiveAd();\n this.activeAdBreakState = undefined;\n }\n\n onAdStarted(adInfo: AdInfo) {\n if (!adInfo.isLinear) {\n return;\n }\n\n this.resetActiveAd();\n this.activeAdState = buildInitialActiveAdState(adInfo);\n this.currentTime = undefined;\n this.activeAdState.adStartupTime = this.adStartupTimestamp ? Date.now() - this.adStartupTimestamp : undefined;\n\n this.startAd(this.activeAdState);\n }\n\n onAdFinished(_ad: AdInfo) {\n if (!this.activeAdBreakState || !this.activeAdState) {\n return;\n }\n\n const activeAdStateCopy = {...this.activeAdState};\n activeAdStateCopy.completed = 1;\n this.resetActiveAd();\n this.completeAd(this.activeAdBreakState, activeAdStateCopy, activeAdStateCopy.adDuration);\n }\n\n onAdSkipped(_ad: AdInfo) {\n if (!this.activeAdBreakState || !this.activeAdState) {\n return;\n }\n\n const activeAdStateCopy = {...this.activeAdState};\n activeAdStateCopy.skipped = 1;\n activeAdStateCopy.skipPosition = this.currentTime;\n activeAdStateCopy.skipPercentage = Utils.calculatePercentage(\n activeAdStateCopy.skipPosition,\n this.activeAdState.adDuration,\n );\n this.resetActiveAd();\n this.completeAd(this.activeAdBreakState, activeAdStateCopy, activeAdStateCopy.skipPosition);\n }\n\n onAdError(payload: AdErrorPayload) {\n const adBreakSample = buildInitialActiveAdBreakState(payload.adBreakInfo);\n\n const transformedError = this.analytics.transformError(\n {code: payload.code, message: payload.message, severity: 'CRITICAL'},\n payload,\n );\n\n adBreakSample.errorCode = transformedError.code;\n adBreakSample.errorData = tryJSONStringify({code: payload.code, message: payload.message});\n adBreakSample.errorMessage = transformedError.message;\n adBreakSample.errorSeverity = transformedError.severity;\n\n let activeAdState: ActiveAdState | undefined;\n let exitPosition: number | undefined;\n if (this.activeAdState && payload.activeAdId && this.activeAdState.adId === payload.activeAdId) {\n activeAdState = this.activeAdState;\n exitPosition = this.currentTime;\n activeAdState.errorPosition = this.currentTime;\n activeAdState.errorPercentage = Utils.calculatePercentage(activeAdState.errorPosition, activeAdState.adDuration);\n }\n this.completeAd(adBreakSample, activeAdState, exitPosition);\n }\n\n onAdClicked(payload: AdClickedPayload) {\n if (!this.activeAdState) {\n return;\n }\n this.activeAdState.adClickthroughUrl = payload.clickThroughUrl;\n this.activeAdState.clicked = 1;\n this.activeAdState.clickPosition = this.currentTime;\n this.activeAdState.clickPercentage = Utils.calculatePercentage(\n this.activeAdState.clickPosition,\n this.activeAdState.adDuration,\n );\n }\n\n onAdQuartile(payload: AdQuartilePayload) {\n if (!this.activeAdState) {\n return;\n }\n if (payload.quartile === AdQuartile.FIRST_QUARTILE) {\n this.activeAdState.quartile1 = 1;\n } else if (payload.quartile === AdQuartile.MIDPOINT) {\n this.activeAdState.midpoint = 1;\n } else if (payload.quartile === AdQuartile.THIRD_QUARTILE) {\n this.activeAdState.quartile3 = 1;\n }\n }\n\n onBeforeUnload() {\n if (this.onBeforeUnLoadEvent) {\n return;\n }\n this.onBeforeUnLoadEvent = true;\n if (!this.activeAdState || !this.activeAdBreakState) {\n return;\n }\n\n const activeAdStateCopy = {...this.activeAdState};\n activeAdStateCopy.closed = 1;\n activeAdStateCopy.closePosition = this.currentTime;\n activeAdStateCopy.closePercentage = Utils.calculatePercentage(\n activeAdStateCopy.closePosition,\n activeAdStateCopy.adDuration,\n );\n this.resetActiveAd();\n this.completeAd(this.activeAdBreakState, activeAdStateCopy, activeAdStateCopy.closePosition);\n }\n\n private sendAnalyticsRequest(activeAdBreakState: ActiveAdBreakState, activeAdState?: ActiveAdState) {\n const adSample: AdSample = {\n // set common fields from playback sample (if already created)\n ...buildAdSample(this.analytics.sample),\n // set ad break fields\n ...activeAdBreakState,\n // set ad fields (if any)\n ...(activeAdState || buildInitialActiveAdState()),\n };\n\n const moduleInfo = this.adapter.getAdModuleInfo();\n adSample.analyticsVersion = VERSION;\n adSample.adModule = moduleInfo.name;\n adSample.adModuleVersion = moduleInfo.version;\n adSample.autoplay = this.adapter.getAutoPlay();\n adSample.pageLoadType = Utils.getPageLoadType();\n\n adSample.time = Date.now();\n adSample.adImpressionId = generateUUID();\n adSample.percentageInViewport = Utils.calculatePercentage(adSample.timeInViewport, adSample.timePlayed);\n this.analytics.backend.sendAdRequest(adSample);\n }\n\n private updatePlayingTime(activeAdState: ActiveAdState) {\n const timestamp = Date.now();\n if (this.beginPlayingTimestamp && this.isPlaying) {\n if (activeAdState.timePlayed !== undefined) {\n activeAdState.timePlayed += timestamp - this.beginPlayingTimestamp;\n }\n if (this.isContainerInViewport() && this.enterViewportTimestamp && activeAdState.timeInViewport !== undefined) {\n activeAdState.timeInViewport += timestamp - this.enterViewportTimestamp;\n }\n }\n }\n\n private startAd(activeAdState: ActiveAdState) {\n activeAdState.started = 1;\n activeAdState.timePlayed = 0;\n activeAdState.timeInViewport = 0;\n activeAdState.adPodPosition = this.adPodPosition;\n const timestamp = Date.now();\n this.beginPlayingTimestamp = timestamp;\n this.enterViewportTimestamp = this.isContainerInViewport() ? timestamp : undefined;\n this.isPlaying = true;\n this.currentTime = 0;\n this.adPodPosition++;\n this.currentTimeInterval = setInterval(() => {\n try {\n if (\n activeAdState &&\n activeAdState.adDuration !== undefined &&\n activeAdState.adDuration > 0 &&\n this.adapter.isLinearAdActive()\n ) {\n this.currentTime = Utils.calculateTime(Math.max(this.adapter.currentTime(), 0));\n }\n } catch (e) {\n logger.log('AdStarted monitoring interval failed and got cleared', e);\n this.resetActiveAd();\n }\n }, AdAnalytics.TIMEOUT_CURRENT_TIME_INTERVAL);\n }\n\n private completeAd(\n activeAdBreakState: ActiveAdBreakState,\n activeAdState: ActiveAdState = buildInitialActiveAdState(),\n exitPosition?: number,\n ) {\n activeAdState.exitPosition = exitPosition;\n activeAdState.playPercentage = Utils.calculatePercentage(activeAdState.exitPosition, activeAdState.adDuration);\n\n // Fallback to set quartile properties (if not set yet)\n // For players that don't emit native quartile events (THEOplayer) we calculate quartile properties based on playPercentage\n if (isNotNullish(activeAdState.playPercentage)) {\n if (activeAdState.quartile1 === 0 && activeAdState.playPercentage >= 25) {\n activeAdState.quartile1 = 1;\n }\n if (activeAdState.midpoint === 0 && activeAdState.playPercentage >= 50) {\n activeAdState.midpoint = 1;\n }\n if (activeAdState.quartile3 === 0 && activeAdState.playPercentage >= 75) {\n activeAdState.quartile3 = 1;\n }\n }\n\n // reset startupTimestamp for the next ad, in case there are multiple ads in one ad break\n this.adStartupTimestamp = Date.now();\n this.updatePlayingTime(activeAdState);\n this.isPlaying = false;\n this.sendAnalyticsRequest(activeAdBreakState, activeAdState);\n }\n\n private resetActiveAd() {\n this.clearCurrentTimeInterval();\n this.activeAdState = undefined;\n }\n\n private clearCurrentTimeInterval() {\n clearInterval(this.currentTimeInterval);\n delete this.currentTime;\n }\n}\n\n/**\n * Used to track the state of the active ad break.\n *\n * It is partial of {@link AdSample} because it's purpose is to build the final {@link AdSample}.\n */\ntype ActiveAdBreakState = Pick<\n AdSample,\n | 'adFallbackIndex'\n | 'adIdPlayer'\n | 'adIsPersistent'\n | 'adOffset'\n | 'adPosition'\n | 'adPreloadOffset'\n | 'adReplaceContentDuration'\n | 'adScheduleTime'\n | 'adTagPath'\n | 'adTagServer'\n | 'adTagType'\n | 'adTagUrl'\n | 'errorCode'\n | 'errorData'\n | 'errorMessage'\n | 'errorSeverity'\n | 'manifestDownloadTime'\n>;\n\nexport function buildInitialActiveAdBreakState(adBreakInfo?: AdBreakInfo): ActiveAdBreakState {\n const state: ActiveAdBreakState = {adFallbackIndex: 0};\n\n if (isNullish(adBreakInfo)) {\n return state;\n }\n\n state.adIdPlayer = adBreakInfo.id;\n state.adReplaceContentDuration = Utils.calculateTimeWithUndefined(adBreakInfo.replaceContentDuration);\n state.adIsPersistent = adBreakInfo.persistent;\n state.adTagType = adBreakInfo.tagType;\n state.adTagUrl = adBreakInfo.tagUrl;\n state.adPreloadOffset = Utils.calculateTimeWithUndefined(adBreakInfo.preloadOffset);\n state.adFallbackIndex = adBreakInfo.fallbackIndex ?? 0;\n state.manifestDownloadTime = Utils.calculateTimeWithUndefined(adBreakInfo.manifestDownloadTime);\n\n if (adBreakInfo.position === 'pre' || adBreakInfo.position === 'post') {\n state.adPosition = adBreakInfo.position;\n } else if (isNotNullish(adBreakInfo.position)) {\n state.adPosition = 'mid';\n state.adOffset = adBreakInfo.position;\n }\n\n if (isNotNullish(state.adTagUrl)) {\n try {\n const adTagUrl = new URL(state.adTagUrl);\n state.adTagServer = adTagUrl.hostname;\n state.adTagPath = adTagUrl.pathname;\n } catch {\n // Invalid URL, leave fields undefined\n }\n }\n\n if (isFiniteNumber(adBreakInfo.scheduleTime)) {\n state.adScheduleTime = Utils.calculateTime(adBreakInfo.scheduleTime);\n }\n\n return state;\n}\n\n/**\n * Used to track the state of the active ad in ad break.\n *\n * It is partial of {@link AdSample} because it's purpose is to build the final {@link AdSample}.\n */\ntype ActiveAdState = Pick<\n AdSample,\n | 'adClickthroughUrl'\n | 'adDescription'\n | 'adDuration'\n | 'adId'\n | 'adPlaybackHeight'\n | 'adPlaybackWidth'\n | 'adPodPosition'\n | 'adSkipAfter'\n | 'adSkippable'\n | 'adStartupTime'\n | 'adSystem'\n | 'adTitle'\n | 'advertiserName'\n | 'apiFramework'\n | 'clicked'\n | 'clickPercentage'\n | 'clickPosition'\n | 'closed'\n | 'closePercentage'\n | 'closePosition'\n | 'completed'\n | 'creativeAdId'\n | 'creativeId'\n | 'errorPercentage'\n | 'errorPosition'\n | 'exitPosition'\n | 'isLinear'\n | 'mediaPath'\n | 'mediaServer'\n | 'mediaUrl'\n | 'midpoint'\n | 'minSuggestedDuration'\n | 'playPercentage'\n | 'quartile1'\n | 'quartile3'\n | 'skipped'\n | 'skipPercentage'\n | 'skipPosition'\n | 'started'\n | 'streamFormat'\n | 'surveyUrl'\n | 'timeInViewport'\n | 'timePlayed'\n | 'universalAdIdRegistry'\n | 'universalAdIdValue'\n | 'videoBitrate'\n | 'wrapperAdsCount'\n>;\n\nexport function buildInitialActiveAdState(adInfo?: AdInfo): ActiveAdState {\n const state: ActiveAdState = {\n clicked: 0,\n closed: 0,\n completed: 0,\n midpoint: 0,\n quartile1: 0,\n quartile3: 0,\n skipped: 0,\n started: 0,\n };\n\n if (isNullish(adInfo)) {\n return state;\n }\n\n state.adClickthroughUrl = adInfo.clickThroughUrl;\n state.adId = adInfo.id;\n state.mediaUrl = adInfo.mediaUrl;\n state.isLinear = adInfo.isLinear;\n state.adPlaybackHeight = adInfo.height;\n state.adPlaybackWidth = adInfo.width;\n state.streamFormat = adInfo.mimeType;\n\n if (isNotNullish(state.mediaUrl)) {\n try {\n const mediaUrl = new URL(state.mediaUrl);\n state.mediaPath = mediaUrl.pathname;\n state.mediaServer = mediaUrl.hostname;\n } catch {\n // Invalid URL, leave fields undefined\n }\n }\n\n if (isNotNullish(adInfo.bitrate)) {\n state.videoBitrate = adInfo.bitrate * 1000;\n }\n\n const vastData = adInfo.vastData;\n if (isNotNullish(vastData)) {\n state.adSystem = vastData.adSystem;\n state.advertiserName = vastData.advertiserName;\n state.apiFramework = vastData.apiFramework;\n state.creativeAdId = vastData.creativeAdId;\n state.creativeId = vastData.creativeId;\n state.universalAdIdRegistry = vastData.universalAdIdRegistry;\n state.universalAdIdValue = vastData.universalAdIdValue;\n state.adDescription = vastData.adDescription;\n state.minSuggestedDuration = Utils.calculateTimeWithUndefined(vastData.minSuggestedDuration);\n state.surveyUrl = vastData.surveyUrl;\n state.adTitle = vastData.adTitle;\n state.wrapperAdsCount = vastData.wrapperAdsCount;\n }\n\n if (isNotNullish(adInfo.skippableAfter)) {\n state.adSkipAfter =\n adInfo.skippableAfter === -1 ? adInfo.skippableAfter : Utils.calculateTime(adInfo.skippableAfter);\n }\n\n state.adSkippable = adInfo.skippable ?? (isNotNullish(state.adSkipAfter) ? state.adSkipAfter >= 0 : undefined);\n state.adDuration = Utils.calculateTimeWithUndefined(adInfo.duration);\n\n return state;\n}\n","import {InternalAdapterAPI} from '../adapters/internal/InternalAdapterAPI';\nimport {AD_TYPE} from '../enums/AdType';\nimport {ErrorCode} from '../enums/ErrorCode';\nimport {PlayerSize} from '../enums/PlayerSize';\nimport {VideoStartFailedReason} from '../enums/VideoStartFailedReason';\nimport {ErrorDetailTrackingSettingsProvider} from '../features/errordetails/ErrorDetailTracking';\nimport {OnErrorDetailEventObject} from '../features/errordetails/OnErrorDetailEventObject';\nimport {FeatureManager} from '../features/FeatureManager';\nimport type {AnalyticsConfig, AnalyticsError} from '../types/AnalyticsConfig';\nimport {AuthenticationCallback} from '../types/AuthenticationCallback';\nimport {CustomDataValues, extractCustomDataFieldsOnly} from '../types/CustomDataValues';\nimport type {QualityChangeEvent} from '../types/EventData';\nimport * as EventData from '../types/EventData';\nimport {FeatureConfigContainer} from '../types/FeatureConfigContainer';\nimport {PlaybackInfo} from '../types/PlaybackInfo';\nimport {Sample} from '../types/Sample';\nimport type {SourceMetadata} from '../types/SourceMetadata';\nimport Timespan from '../types/Timespan';\nimport {\n applySourceMetadataToAnalyticsConfig,\n getDeviceInformationFromAnalyticsConfig,\n getDomainFromAnalyticsConfig,\n guardAgainstDuplicatedUserId,\n guardConfigChangeAgainstMissingIsLive,\n guardConfigChangeAgainstMissingTitle,\n mergeAnalyticsConfig,\n} from '../utils/analyticsConfigUtils';\nimport {CodecHelper} from '../utils/CodecHelper';\nimport {globalScope} from '../utils/globalScope';\nimport {\n getGlobalNavigatorLanguage,\n getGlobalNavigatorUserAgent,\n getGlobalScreenDimensions,\n hasGlobalWebOSApi,\n} from '../utils/globalScopeUtils';\nimport {logger} from '../utils/Logger';\nimport {isFiniteNumber, isNumber} from '../utils/numberUtils';\nimport {clearSampleStateValues, getDefaultSamplePath} from '../utils/sampleUtils';\nimport {isBlank, isValidString} from '../utils/stringUtils';\nimport * as Utils from '../utils/Utils';\nimport {isErrorSeverity, isNotNullish, isNullish, tryJSONStringify} from '../utils/Utils';\nimport {generateUUID} from '../utils/uuidUtils';\nimport {VERSION} from '../utils/Version';\nimport {getWebOSTVModelName} from '../utils/WebOSUtils';\n\nimport {AdAnalytics} from './AdAnalytics';\nimport {Backend} from './Backend';\nimport {BackendFactory} from './BackendFactory';\nimport {EventDispatcher, Subscribable} from './EventDispatcher';\nimport {IdenticalErrorReportingLimiter} from './IdenticalErrorReportingLimiter';\nimport {NoOpBackend} from './NoOpBackend';\nimport {SessionPersistenceHandler} from './SessionPersistenceHandler';\nimport {\n isSsaiEngagementErrorData,\n isSsaiEngagementQuartileData,\n isSsaiEngagementStartedData,\n SsaiEngagementInteractionData,\n} from './ssai/ssaiEngagementInteractionData';\nimport {createErrorAdSample, createQuartileAdSample, createStartedAdSample} from './ssai/ssaiUtils';\n\nexport class Analytics {\n get version(): string {\n return VERSION;\n }\n\n static version: string = VERSION;\n\n private readonly adAnalytics: AdAnalytics | undefined;\n\n sample: Sample;\n\n private hasSentStartupSample = false;\n backend!: Backend;\n readonly errorDetailTrackingSettingsProvider: ErrorDetailTrackingSettingsProvider;\n\n private config: AnalyticsConfig;\n private droppedSampleFrames = 0;\n /**\n * Used to save and store player startup time once the \"setup sample\" is created, to pick it up and use it to set\n * the \"startup sample\" property \"startupTime\" as a sum of player and video startup time.\n */\n private playerStartupTime = 0;\n\n private readonly authenticationCallback: AuthenticationCallback = {\n authenticationCompleted: (success: boolean, featureConfigs?: FeatureConfigContainer) => {\n this.featureManager.configureFeatures(success, featureConfigs);\n },\n };\n\n // used only in tests to inject mocks\n constructor(\n initialAnalyticsConfig: AnalyticsConfig,\n private readonly adapter: InternalAdapterAPI,\n private readonly backendFactory: BackendFactory,\n private readonly sessionHandler: SessionPersistenceHandler,\n private readonly featureManager: FeatureManager<FeatureConfigContainer>,\n private readonly onErrorDetailEventDispatcher: EventDispatcher<OnErrorDetailEventObject>,\n private readonly identicalErrorReportingLimiter: IdenticalErrorReportingLimiter,\n ) {\n this.config = initialAnalyticsConfig;\n this.sessionHandler = new SessionPersistenceHandler(this.config);\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const that = this;\n this.errorDetailTrackingSettingsProvider = {\n get domain() {\n return getDomainFromAnalyticsConfig(that.config);\n },\n get licenseKey() {\n return that.config.key ?? '';\n },\n get impressionId() {\n return that.getCurrentImpressionId() ?? '';\n },\n get collectorConfig() {\n return that.config.config;\n },\n };\n\n const licenseKeyReceivedUnsubscriber = this.adapter.onLicenseKeyReceived.subscribe(\n (eventArgs: {licenseKey: string}) => {\n if (!this.config.key) {\n this.config.key = eventArgs.licenseKey;\n }\n licenseKeyReceivedUnsubscriber();\n },\n );\n\n this.sample = this.buildInitialSample();\n this.droppedSampleFrames = 0;\n this.init();\n this.setupStateMachineCallbacks();\n\n // initialize adapter (start to listen to the player events and call the callbacks accordingly)\n const features = this.adapter.initialize(this);\n this.featureManager.registerFeatures(features);\n\n if (this.adapter.adModule) {\n // this needs to be called after the adapter has been initialized and has created adModule (if any)\n this.adAnalytics = new AdAnalytics(this, this.adapter.adModule);\n }\n }\n\n get errorDetailSubscribable(): Subscribable<OnErrorDetailEventObject> {\n return this.onErrorDetailEventDispatcher;\n }\n\n init() {\n if (\n this.adapter.supportsDeferredLicenseLoading !== true &&\n (!isValidString(this.config.key) || isBlank(this.config.key))\n ) {\n logger.errorMessageToUser('Invalid analytics license key provided');\n return;\n }\n\n logger.initialize(this.config.debug);\n\n this.featureManager.resetFeatures();\n\n const domain = getDomainFromAnalyticsConfig(this.config);\n this.backend = this.backendFactory.createBackend(\n this.config,\n {key: this.config.key, domain, version: VERSION},\n this.adapter,\n this.authenticationCallback,\n );\n\n this.hasSentStartupSample = false;\n this.identicalErrorReportingLimiter.reset();\n\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n this.sample.impressionId = generateUUID();\n this.sample.userId = this.sessionHandler.userId;\n\n if (this.adapter.videoCompletionTracker) {\n this.adapter.videoCompletionTracker.reset();\n }\n\n this.adapter.qualityChangeService.resetValues();\n this.adapter.ssaiService.resetSourceRelatedState();\n }\n\n setConfigParameters() {\n this.sample.key = this.config.key;\n this.sample.playerKey = this.config.playerKey;\n if (this.config.player) {\n this.sample.player = this.config.player;\n }\n this.sample.domain = getDomainFromAnalyticsConfig(this.config);\n\n this.sample.deviceInformation = getDeviceInformationFromAnalyticsConfig(this.config);\n\n this.sample.isLive = isNotNullish(this.config.isLive) ? this.config.isLive : false;\n\n this.sample.cdnProvider = this.config.cdnProvider;\n this.sample.videoId = this.config.videoId;\n this.sample.videoTitle = this.config.title;\n this.sample.customUserId = this.config.userId ?? this.config.customUserId;\n\n Utils.transferCustomDataFields(this.config, this.sample);\n\n this.sample.experimentName = this.config.experimentName;\n }\n\n setAutoDetectedDeviceInformation(): void {\n // do not overwrite existing model value (set through config)\n if (isNotNullish(this.sample.deviceInformation?.model)) {\n return;\n }\n\n if (!hasGlobalWebOSApi()) return;\n\n const modelName = getWebOSTVModelName();\n if (isNullish(modelName)) return;\n\n this.sample.deviceInformation = this.sample.deviceInformation ?? {};\n this.sample.deviceInformation.model = modelName;\n }\n\n private setupStateMachineCallbacks() {\n // All of these are called in the onLeaveState Method.\n // So it's the last sample\n this.adapter.stateMachineCallbacks.setup = (duration: number, state: string) => {\n logger.log(\n 'Setup bitmovin analytics ' + this.sample.analyticsVersion + ' with impressionId: ' + this.sample.impressionId,\n );\n\n this.setDuration(duration);\n this.setState(state);\n this.sample.playerStartupTime = duration;\n this.playerStartupTime = this.sample.playerStartupTime;\n\n const navigationStart = globalScope.performance?.timing?.navigationStart;\n if (isNotNullish(navigationStart) && isFiniteNumber(navigationStart)) {\n // round the final time to a whole number to avoid unnecessary precision (performance API returns a high-precision timestamp as double)\n const pageLoadTime = Math.round(Date.now() - globalScope.performance.timing.navigationStart);\n this.sample.pageLoadTime = pageLoadTime;\n }\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.startup = (duration: number, state: string) => {\n this.setState(state);\n this.sample.supportedVideoCodecs = CodecHelper.supportedVideoFormats;\n // videoStartupTime has to be > 0 on startup sample\n // it is used to mark a successfull impression and billing depends on it\n const sanitizeVideoStartupTime = Math.max(duration, 1);\n this.setDuration(sanitizeVideoStartupTime);\n this.sample.videoStartupTime = sanitizeVideoStartupTime;\n this.sample.startupTime = (this.playerStartupTime || 0) + sanitizeVideoStartupTime;\n\n this.sample.autoplay = this.adapter.getAutoPlay();\n\n const drmPerformance = this.adapter.getDrmPerformanceInfo();\n if (isNotNullish(drmPerformance)) {\n this.sample.drmType = drmPerformance.drmType;\n this.sample.drmLoadTime = drmPerformance.drmLoadTime;\n }\n\n const {videoBitrate, audioBitrate} = this.adapter.getCurrentPlaybackInfo();\n // set the flag to allow quality change events after startup and try to set the startup bitrate values (if any)\n // as the initial ones, to be able to compare them with future quality changes\n this.adapter.qualityChangeService.setStartupHasFinished(videoBitrate, audioBitrate);\n\n this.hasSentStartupSample = true;\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.programChange = (sourceMetadata: SourceMetadata) => {\n // reset analytics\n // player is already loaded, so it is irrelevant for the program change startup sample\n this.playerStartupTime = 0;\n\n // apply source metadata to config\n this.config = applySourceMetadataToAnalyticsConfig(this.config, sourceMetadata);\n\n // reset sample to init values\n this.sample = this.buildInitialSample();\n // apply a source metadata path to the sample (if any)\n this.sample.path = isValidString(sourceMetadata.path) ? sourceMetadata.path : getDefaultSamplePath();\n\n // reinitialize to finish reset of the Analytics module\n this.init();\n\n // build startup \"programchange\" sample\n this.setState('programchange');\n this.sample.isProgramChange = true;\n this.sample.supportedVideoCodecs = CodecHelper.supportedVideoFormats;\n // videoStartupTime has to be > 0 on the startup sample\n // it is used to mark a successful impression and billing depends on it\n const programChangeVideoStartupTime = 1;\n this.setDuration(programChangeVideoStartupTime);\n this.sample.videoStartupTime = programChangeVideoStartupTime;\n this.sample.startupTime = programChangeVideoStartupTime; // is not affected now by player startup time\n\n this.sample.autoplay = this.adapter.getAutoPlay();\n\n // DRM load time is only important when we load the source, DRM request does not happen between active playback\n // so it can't happen during the program change\n this.sample.drmType = undefined;\n this.sample.drmLoadTime = undefined;\n\n const {videoBitrate, audioBitrate} = this.adapter.getCurrentPlaybackInfo();\n // set the flag to allow quality change events after startup and try to set the startup bitrate values (if any)\n // as the initial ones, to be able to compare them with future quality changes\n this.adapter.qualityChangeService.setStartupHasFinished(videoBitrate, audioBitrate);\n\n this.hasSentStartupSample = true;\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.updateSourceMetadata = (sourceMetadata: SourceMetadata) => {\n // apply source metadata to config\n this.config = applySourceMetadataToAnalyticsConfig(this.config, sourceMetadata);\n // new config should be immediately applied to the current sample\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n // apply a source metadata path to the sample (if any)\n this.sample.path = isValidString(sourceMetadata.path) ? sourceMetadata.path : getDefaultSamplePath();\n };\n\n this.adapter.stateMachineCallbacks.playing = (duration: number, state: string) => {\n this.setDuration(duration);\n this.setState(state);\n this.sample.played = duration;\n this.setCompletionValues();\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.unload = (duration: number, state: string) => {\n let videoStartForClosedState = this.sample.videoTimeStart;\n if (state === 'playing') {\n this.setDuration(duration);\n this.setState(state);\n this.sample.played = duration;\n this.setCompletionValues();\n if (isNumber(this.sample.videoTimeEnd)) {\n videoStartForClosedState = this.sample.videoTimeEnd;\n }\n\n this.backend.sendUnloadRequest(this.sample);\n clearSampleStateValues(this.sample);\n }\n\n if (this.hasSentStartupSample) {\n this.setVideoTimeStart(videoStartForClosedState);\n this.setVideoTimeEnd(videoStartForClosedState);\n this.setState('closed');\n\n this.backend.sendUnloadRequest(this.sample);\n clearSampleStateValues(this.sample);\n }\n };\n\n this.adapter.stateMachineCallbacks.heartbeat = (duration, state, heartbeatPayload) => {\n this.setState(state);\n this.setDuration(duration);\n\n this.sample = {\n ...this.sample,\n ...heartbeatPayload,\n };\n\n if (state === 'playing') {\n this.setCompletionValues();\n }\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.qualitychange = (event: QualityChangeEvent) => {\n this.adapter.qualityChangeService.startResetInterval();\n this.adapter.qualityChangeService.increaseCounter();\n\n if (this.adapter.qualityChangeService.hasExceededQualityChangeThreshold()) {\n this.adapter.stateMachineCallbacks.error({\n code: ErrorCode.QUALITY_CHANGE_THRESHOLD_EXCEEDED.code,\n message: ErrorCode.QUALITY_CHANGE_THRESHOLD_EXCEEDED.message,\n errorSeverity: ErrorCode.QUALITY_CHANGE_THRESHOLD_EXCEEDED.errorSeverity,\n legacyData: undefined,\n data: {},\n currentTime: event.currentTime,\n });\n return;\n }\n\n this.setState('qualitychange');\n this.setDuration(0);\n this.adapter.stateMachineCallbacks.setVideoTimeEndFromEvent(event);\n this.adapter.stateMachineCallbacks.setVideoTimeStartFromEvent(event);\n this.adapter.stateMachineCallbacks.updateSampleQualityInfo(event);\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.updateSampleQualityInfo = (event: QualityChangeEvent) => {\n if (event.type === 'audio') {\n if (isNumber(event.bitrate)) {\n this.sample.audioBitrate = event.bitrate;\n }\n if (isValidString(event.codec)) {\n this.sample.audioCodec = event.codec;\n }\n } else if (event.type === 'video') {\n if (isNumber(event.bitrate)) {\n this.sample.videoBitrate = event.bitrate;\n }\n if (isValidString(event.codec)) {\n this.sample.videoCodec = event.codec;\n }\n if (isNumber(event.height)) {\n this.sample.videoPlaybackHeight = event.height;\n }\n if (isNumber(event.width)) {\n this.sample.videoPlaybackWidth = event.width;\n }\n }\n };\n\n this.adapter.stateMachineCallbacks.audiotrack_changing = () => {\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.pause = (duration: number, state: string) => {\n this.setDuration(duration);\n this.setState(state);\n\n this.sample.paused = duration;\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.seeking = (duration: number) => {\n this.setDuration(duration);\n this.setState('seeking');\n this.sample.seeked = duration;\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.rebuffering = (duration: number, state: string) => {\n this.setDuration(duration);\n this.setState(state);\n\n this.sample.buffered = duration;\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.videoStartFailed = (duration, reason) => {\n this.setState('startup');\n this.sample.videoStartFailed = true;\n this.sample.videoStartFailedReason = reason;\n this.sample.duration = duration;\n\n if (reason === VideoStartFailedReason.PLAYER_ERROR) {\n // on player error we should not send a video startup sample\n return;\n }\n\n if (reason === VideoStartFailedReason.TIMEOUT) {\n this.sample.errorCode = ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.code;\n this.sample.errorMessage = ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.message;\n this.sample.errorSeverity = ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.errorSeverity;\n\n this.onErrorDetailEventDispatcher.dispatch({\n code: ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.code,\n message: ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.message,\n severity: ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.errorSeverity,\n });\n }\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.error = (event: Readonly<EventData.ErrorEvent>) => {\n const error = this.transformError(\n {code: event.code, message: event.message, severity: event.errorSeverity ?? 'CRITICAL'},\n event.originalError,\n );\n\n if (error.code && !this.identicalErrorReportingLimiter.shouldReportError(error.code, error.severity)) {\n logger.log(\n `Bitmovin Analytics: Processing of the error with code ${error.code} was ignored because the error limit was exceeded.`,\n );\n return;\n }\n\n this.adapter.stateMachineCallbacks.setVideoTimeEndFromEvent(event);\n this.adapter.stateMachineCallbacks.setVideoTimeStartFromEvent(event);\n\n this.setState('error');\n this.setDuration(0);\n this.sample.errorCode = error.code;\n this.sample.errorMessage = error.message;\n this.sample.errorSeverity = error.severity;\n this.sample.errorData = tryJSONStringify(event.legacyData);\n this.sample.errorSegments = this.adapter.getSegmentInfo().map((s) => s.name);\n\n if (this.adapter.onError) {\n this.adapter.onError();\n }\n\n this.onErrorDetailEventDispatcher.dispatch({\n code: error.code,\n message: error.message,\n severity: error.severity,\n errorData: event.data,\n });\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.ad = (duration: number, state: string) => {\n this.setDuration(duration);\n this.setState(state);\n this.sample.ad = AD_TYPE.CSAI;\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.mute = () => {\n this.sample.isMuted = true;\n };\n\n this.adapter.stateMachineCallbacks.unMute = () => {\n this.sample.isMuted = false;\n };\n\n this.adapter.stateMachineCallbacks.subtitle_changing = () => {\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.setVideoTimeEndFromEvent = (analyticsEventBase) => {\n // if we don't have the current playback time, skip and do nothing\n if (!isNumber(analyticsEventBase?.currentTime)) {\n return;\n }\n\n this.setVideoTimeEnd(Utils.calculateTime(analyticsEventBase.currentTime));\n };\n\n this.adapter.stateMachineCallbacks.setVideoTimeStartFromEvent = (analyticsEventBase) => {\n // if we don't have the current playback time, skip and do nothing\n if (!isNumber(analyticsEventBase?.currentTime)) {\n return;\n }\n\n this.setVideoTimeStart(Utils.calculateTime(analyticsEventBase.currentTime));\n };\n\n this.adapter.stateMachineCallbacks.manualSourceChange = (event: {config: AnalyticsConfig}) => {\n this.adapter.resetSourceRelatedState();\n this.sample = this.buildInitialSample();\n this.droppedSampleFrames = 0;\n this.playerStartupTime = 0;\n this.config = Object.keys(event.config).length > 0 ? event.config : this.config;\n this.init();\n };\n\n this.adapter.stateMachineCallbacks.initialSourceChange = (event: {config: AnalyticsConfig}) => {\n this.config = event.config;\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n };\n\n // The video has ended and we set up for a new impression\n this.adapter.stateMachineCallbacks.end = () => {\n // !!!! THIS IS OLD AND WRONG IMPLEMENTATION !!!!\n // (check deprecation comment on callback)\n this.sample = this.buildInitialSample();\n this.droppedSampleFrames = 0;\n this.playerStartupTime = 0;\n this.init();\n };\n\n this.adapter.stateMachineCallbacks.release = () => {\n this.backend = new NoOpBackend();\n this.adAnalytics?.release();\n this.adapter.qualityChangeService.stopResetInterval();\n this.identicalErrorReportingLimiter.reset();\n };\n\n this.adapter.stateMachineCallbacks.customdatachange = (_duration, _state, eventData) => {\n if (isNotNullish(eventData?.customDataValues)) {\n this.changeCustomData(eventData.customDataValues);\n }\n };\n }\n\n sourceChange = (config: AnalyticsConfig | null | undefined) => {\n logger.log('Processing Source Change for Analytics', config);\n if (isNullish(config)) {\n this.adapter.sourceChange(this.config);\n return;\n }\n\n guardConfigChangeAgainstMissingTitle(this.config, config);\n guardConfigChangeAgainstMissingIsLive(this.config, config);\n guardAgainstDuplicatedUserId(config);\n\n const newConfig = mergeAnalyticsConfig(this.config, config);\n this.adapter.sourceChange(newConfig);\n };\n\n setCustomDataOnce = (values: CustomDataValues) => {\n // save old config to be able to return previous custom data values once the sample is sent\n const oldConfig = {...this.config};\n\n this.setState('customdatachange');\n\n this.sendSample(values);\n // this method doesn't call changeCustomData() second time because in that method we have check for null values\n // to prevent overriding existing customData values with null if some field in object doesn't have value\n // because of that if some customData field had previous value null and it got changed to something else\n // it will not be possible to return it back to null using that method\n this.config = {...oldConfig};\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n };\n\n setCustomData = (values: CustomDataValues) => {\n this.adapter.setCustomData(values);\n };\n\n getCurrentImpressionId = (): string | undefined => {\n return this.sample.impressionId;\n };\n\n getUserId = (): string => {\n return this.sessionHandler.userId;\n };\n\n setDuration(duration: number) {\n this.sample.duration = duration;\n }\n\n setState(state: string) {\n this.sample.state = state;\n }\n\n setPlaybackInfoFromAdapter() {\n const info = this.adapter.getCurrentPlaybackInfo();\n if (!info) {\n return;\n }\n\n // if set, we always apply `config.isLive` in favor of `info.isLive`\n this.sample.isLive = isNotNullish(this.config.isLive) ? this.config.isLive : info.isLive;\n // if `isLive` is still not defined, we set it to default `false` value\n if (isNullish(this.sample.isLive)) {\n this.sample.isLive = false;\n }\n\n if (isValidString(info.size)) {\n this.sample.size = info.size;\n }\n if (isValidString(info.playerTech)) {\n this.sample.playerTech = info.playerTech;\n }\n if (isNumber(info.videoDuration)) {\n this.sample.videoDuration = Utils.calculateTime(info.videoDuration || 0);\n }\n if (isValidString(info.streamFormat)) {\n this.sample.streamFormat = info.streamFormat;\n }\n if (isValidString(info.mpdUrl)) {\n this.sample.mpdUrl = info.mpdUrl;\n }\n if (isValidString(info.m3u8Url)) {\n this.sample.m3u8Url = info.m3u8Url;\n }\n if (isValidString(info.progUrl)) {\n this.sample.progUrl = info.progUrl;\n }\n if (isNumber(info.videoWindowWidth)) {\n this.sample.videoWindowWidth = info.videoWindowWidth;\n }\n if (isNumber(info.videoWindowHeight)) {\n this.sample.videoWindowHeight = info.videoWindowHeight;\n }\n if (isNumber(info.screenHeight)) {\n this.sample.screenHeight = info.screenHeight;\n }\n if (isNumber(info.screenWidth)) {\n this.sample.screenWidth = info.screenWidth;\n }\n if (Utils.isBoolean(info.isMuted)) {\n this.sample.isMuted = info.isMuted;\n }\n if (Utils.isBoolean(info.isCasting)) {\n this.sample.isCasting = info.isCasting;\n }\n if (isValidString(info.castTech)) {\n this.sample.castTech = info.castTech;\n }\n if (isValidString(info.videoTitle) && !this.config.title) {\n this.sample.videoTitle = info.videoTitle;\n }\n if (isValidString(info.audioCodec)) {\n this.sample.audioCodec = info.audioCodec;\n }\n if (isValidString(info.videoCodec)) {\n this.sample.videoCodec = info.videoCodec;\n }\n if (isValidString(info.audioLanguage)) {\n this.sample.audioLanguage = info.audioLanguage;\n }\n if (Utils.isBoolean(info.subtitleEnabled)) {\n this.sample.subtitleEnabled = info.subtitleEnabled;\n }\n if (isValidString(info.subtitleLanguage)) {\n this.sample.subtitleLanguage = info.subtitleLanguage;\n } else {\n this.sample.subtitleLanguage = undefined;\n }\n if (isNumber(info.droppedFrames)) {\n this.sample.droppedFrames = Math.max(info.droppedFrames - this.droppedSampleFrames, 0);\n this.droppedSampleFrames = info.droppedFrames;\n }\n }\n\n sendSample(customDataOnceValues?: CustomDataValues) {\n this.setPlaybackInfoFromAdapter();\n this.sample.time = Utils.getCurrentTimestamp();\n\n // get current download speed info from the adapter and set it on the sample before sending it\n this.sample.downloadSpeedInfo = this.adapter.getDownloadSpeedInfo();\n // reset current download speed info measures in the adapter to start fresh for the next sample,\n // so we always have the info for the current sample only\n this.adapter.resetDownloadSpeedInfoMeasures();\n\n this.adapter.ssaiService.manipulate(this.sample);\n\n // if we have received custom data from the setCustomDataOnce API call, we need to set\n // them as \"the last one\" (we need to override normal customData and SSAI custom data)\n if (customDataOnceValues != null) {\n this.changeCustomData(customDataOnceValues);\n }\n\n // Initial quality info should be available for the first sample after setup, so if there is no quality info yet, we try to set it *before* sending a sample.\n // In the general case, a qualitychange event first triggers a sample of the state we were in before the qualitychange sample itself is sent.\n // So to only report quality updates on the qualitychange sample and not the ones before it, we need to update the quality info *after* sending a sample,\n // making it available for future samples (e.g. qualitychange sample).\n // We only check videoBitrate and not audioBitrate since the latter is often reported as null/0 anyways.\n if (isNullish(this.sample.videoBitrate) || this.sample.videoBitrate <= 0) {\n setQualityInfoOnSample(this.sample, this.adapter.getCurrentPlaybackInfo());\n const copySample = {...this.sample};\n this.backend.sendRequest(copySample);\n } else {\n const copySample = {...this.sample};\n this.backend.sendRequest(copySample);\n setQualityInfoOnSample(this.sample, this.adapter.getCurrentPlaybackInfo());\n }\n\n // clear sample state values after sending a sample\n clearSampleStateValues(this.sample);\n }\n\n sendSsaiEngagementAdSample(data: SsaiEngagementInteractionData) {\n if (this.config.config?.ssaiEngagementTrackingEnabled !== true) {\n // if not enabled in config, do not send SSAI engagement AdSample\n return;\n }\n\n if (isSsaiEngagementStartedData(data)) {\n const ssaiAdSample = createStartedAdSample(this.sample, data);\n\n this.backend.sendAdRequest(ssaiAdSample);\n return;\n }\n\n if (isSsaiEngagementQuartileData(data)) {\n const ssaiAdSample = createQuartileAdSample(this.sample, data);\n\n this.backend.sendAdRequest(ssaiAdSample);\n return;\n }\n\n if (isSsaiEngagementErrorData(data)) {\n data.analyticsError = this.transformError(data.analyticsError, data.originalError);\n\n const ssaiErrorAdSample = createErrorAdSample(this.sample, data);\n\n this.backend.sendAdRequest(ssaiErrorAdSample);\n return;\n }\n }\n\n /**\n * This method sanitizes the input and updates the analytics config.\n * @param values Object containing the customData and other fields\n */\n private changeCustomData = (values: CustomDataValues) => {\n this.config = {\n ...this.config,\n ...extractCustomDataFieldsOnly(values),\n };\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n };\n\n private setCompletionValues() {\n if (this.adapter.videoCompletionTracker) {\n const completed = this.adapter.videoCompletionTracker.addWatched({\n start: this.sample.videoTimeStart,\n end: this.sample.videoTimeEnd,\n } as Timespan);\n const completedTotal = this.adapter.videoCompletionTracker.getCompletionPercentage();\n\n if (!Number.isNaN(completed) && !Number.isNaN(completedTotal)) {\n this.sample.completed = completed;\n this.sample.completedTotal = completedTotal;\n }\n }\n }\n\n private setVideoTimeStart(value: number | undefined) {\n this.sample.videoTimeStart = value;\n }\n\n private setVideoTimeEnd(value: number | undefined) {\n this.sample.videoTimeEnd = value;\n }\n\n transformError(error: AnalyticsError, originalError: any): AnalyticsError {\n const analyticsError = {\n code: error.code,\n message: error.message,\n severity: error.severity,\n };\n\n try {\n const transformedError = this.config.config?.errorTransformerCallback?.transform(analyticsError, {\n originalError: originalError,\n });\n\n analyticsError.code = isNumber(transformedError?.code) ? transformedError?.code : analyticsError.code;\n analyticsError.message = isValidString(transformedError?.message)\n ? transformedError?.message\n : analyticsError.message;\n analyticsError.severity =\n isValidString(transformedError?.severity) && isErrorSeverity(transformedError?.severity)\n ? transformedError!.severity\n : analyticsError.severity;\n } catch (error) {\n logger.error('Error in errorTransformerCallback', error);\n }\n\n return analyticsError;\n }\n\n private buildInitialSample(): Sample {\n const player = this.config.player || this.adapter.getPlayerName();\n const screenDimensions = getGlobalScreenDimensions();\n\n return {\n ad: 0,\n analyticsVersion: VERSION,\n audioBitrate: 0,\n buffered: 0,\n completedTotal: 0,\n droppedFrames: 0,\n duration: 0,\n isLive: this.config.isLive ?? false,\n language: getGlobalNavigatorLanguage(),\n pageLoadTime: 0,\n pageLoadType: Utils.getPageLoadType(),\n path: getDefaultSamplePath(),\n paused: 0,\n platform: 'web',\n played: 0,\n player,\n playerStartupTime: 0,\n playerTech: this.adapter.getPlayerTech(),\n screenHeight: screenDimensions?.height,\n screenWidth: screenDimensions?.width,\n seeked: 0,\n size: PlayerSize.Window,\n startupTime: 0,\n time: 0,\n userAgent: getGlobalNavigatorUserAgent(),\n version: player + '-' + this.adapter.getPlayerVersion(),\n videoBitrate: 0,\n videoDuration: 0,\n videoPlaybackHeight: 0,\n videoPlaybackWidth: 0,\n videoStartupTime: 0,\n videoTimeEnd: 0,\n videoTimeStart: 0,\n videoWindowHeight: 0,\n videoWindowWidth: 0,\n };\n }\n\n static create(config: AnalyticsConfig, adapter: InternalAdapterAPI): Analytics {\n const backendFactory: BackendFactory = new BackendFactory();\n const sessionHandler: SessionPersistenceHandler = new SessionPersistenceHandler(config);\n const featureManager = new FeatureManager<FeatureConfigContainer>();\n const onErrorDetailEventDispatcher = new EventDispatcher<OnErrorDetailEventObject>();\n const identicalErrorReportingLimiter = new IdenticalErrorReportingLimiter();\n return new Analytics(\n config,\n adapter,\n backendFactory,\n sessionHandler,\n featureManager,\n onErrorDetailEventDispatcher,\n identicalErrorReportingLimiter,\n );\n }\n}\n\n// We separate the quality info from `setPlaybackInfoFromAdapter` to be able to explicitly set/update the quality info only when it changes.\nexport function setQualityInfoOnSample(sample: Sample, playbackInfo: PlaybackInfo) {\n if (isNumber(playbackInfo.videoPlaybackHeight)) {\n sample.videoPlaybackHeight = playbackInfo.videoPlaybackHeight;\n }\n if (isNumber(playbackInfo.videoPlaybackWidth)) {\n sample.videoPlaybackWidth = playbackInfo.videoPlaybackWidth;\n }\n if (isNumber(playbackInfo.videoBitrate)) {\n sample.videoBitrate = playbackInfo.videoBitrate;\n }\n if (isNumber(playbackInfo.audioBitrate)) {\n sample.audioBitrate = playbackInfo.audioBitrate;\n }\n}\n","import {DeferredLicenseLoadingAdapterAPI} from '../adapters/internal/DeferredLicenseLoadingAdapterAPI';\nimport {AnalyticsConfig, CollectorConfig} from '../types/AnalyticsConfig';\nimport {AuthenticationCallback} from '../types/AuthenticationCallback';\nimport {LicensingRequest} from '../types/LicensingRequest';\nimport {LicenseCall} from '../utils/LicenseCall';\nimport {ANALYTICS_BACKEND_BASE_URL} from '../utils/Settings';\n\nimport {Backend} from './Backend';\nimport {DebuggingBackend} from './DebuggingBackend';\nimport {LicenseCheckingBackend} from './LicenseCheckingBackend';\nimport {LongPlaytimeFilteringBackend} from './LongPlaytimeFilteringBackend';\nimport {NoOpBackend} from './NoOpBackend';\nimport {SequenceNumberBackend} from './SequenceNumberBackend';\n\nexport interface InternalCollectorConfig extends CollectorConfig {\n /**\n * Internal \"hidden\" collector config property.\n *\n * It is used only by the Bitmovin Player Testautomation Suite to insert \"AssertionBackend\" and to be able to intercept\n * all backend requests, thus enabling to test and verify of those requests.\n *\n * @see https://github.com/bitmovin-engineering/player-testing/blob/develop/lib/bitdashPlayerTest/analytics/AnalyticsAssertionBackend.ts\n */\n wrapBackend: (innerBackend: Backend) => Backend;\n}\n\nexport class BackendFactory {\n createBackend(\n analyticsConfig: AnalyticsConfig,\n licensingRequest: LicensingRequest,\n adapter: DeferredLicenseLoadingAdapterAPI,\n authenticationCallback: AuthenticationCallback,\n ): Backend {\n if (!this.isEnabled(analyticsConfig)) {\n return new NoOpBackend();\n }\n const inner = this.createInnerBackend(analyticsConfig, licensingRequest, adapter, authenticationCallback);\n return this.decorateWithDebuggingBackend(analyticsConfig, inner);\n }\n\n private decorateWithDebuggingBackend(config: AnalyticsConfig, backend: Backend): Backend {\n if (config.debug) {\n return new DebuggingBackend(config, backend);\n }\n return backend;\n }\n\n private decorateWithBackendFromConfigIfAvailable(analyticsConfig: AnalyticsConfig, innerBackend: Backend): Backend {\n if (\n analyticsConfig !== undefined &&\n analyticsConfig.config !== undefined &&\n (analyticsConfig.config as InternalCollectorConfig).wrapBackend !== undefined\n ) {\n return (analyticsConfig.config as InternalCollectorConfig).wrapBackend(innerBackend);\n }\n\n return innerBackend;\n }\n\n private isEnabled(analyticsConfig: AnalyticsConfig): boolean {\n return analyticsConfig.config === undefined || analyticsConfig.config.enabled !== false;\n }\n\n private createInnerBackend(\n analyticsConfig: AnalyticsConfig,\n licensingRequest: LicensingRequest,\n adapter: DeferredLicenseLoadingAdapterAPI,\n authenticationCallback: AuthenticationCallback,\n ): Backend {\n const backendUrl = (analyticsConfig.config && analyticsConfig.config.backendUrl) || ANALYTICS_BACKEND_BASE_URL;\n let innerBackend: Backend = new LicenseCheckingBackend(\n licensingRequest,\n LicenseCall,\n backendUrl,\n adapter,\n authenticationCallback,\n );\n innerBackend = this.decorateWithBackendFromConfigIfAvailable(analyticsConfig, innerBackend);\n\n const sequenceNumberAssigningBackend = new SequenceNumberBackend(innerBackend);\n return new LongPlaytimeFilteringBackend(sequenceNumberAssigningBackend);\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {AnalyticsConfig, AnalyticsDebugConfig} from '../types/AnalyticsConfig';\nimport type {Sample} from '../types/Sample';\nimport {logger} from '../utils/Logger';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `DebuggingBackend` is responsible for printing debugging information\n * before forwarding the requests to the specified underlying backend.\n *\n * This allows for inspection of specific fields in the sample data before it is sent.\n * The fields can be specified through the {@link AnalyticsDebugConfig#fields}.\n *\n * @implements {Backend}\n * */\nexport class DebuggingBackend implements Backend {\n private readonly underlying: Backend;\n private readonly debugFields: string[] | undefined;\n\n constructor(config: AnalyticsConfig, underlying: Backend) {\n this.underlying = underlying;\n if (config.debug && (config.debug as AnalyticsDebugConfig).fields) {\n this.debugFields = (config.debug as AnalyticsDebugConfig).fields;\n }\n }\n\n sendRequest(sample: Sample): void {\n this.printFields(sample);\n this.underlying.sendRequest(sample);\n }\n\n sendUnloadRequest(sample: Sample): void {\n this.printFields(sample);\n this.underlying.sendUnloadRequest(sample);\n }\n\n sendRequestSynchronous(sample: Sample): void {\n this.printFields(sample);\n this.underlying.sendRequestSynchronous(sample);\n }\n\n sendAdRequest(adSample: AdSample): void {\n this.underlying.sendAdRequest(adSample);\n }\n\n private printFields(sample: Sample) {\n if (this.debugFields && this.debugFields.length) {\n const fields = {};\n this.debugFields.forEach((f) => (fields[f] = sample[f]));\n logger.table([fields]);\n }\n }\n}\n","export interface Subscribable<TArgs> {\n subscribe(callback: EventHandler<TArgs>): () => void;\n unsubscribe(callback: EventHandler<TArgs>);\n}\n\ntype EventHandler<TArgs> = (args: TArgs) => void;\n\nexport class EventDispatcher<TArgs> implements Subscribable<TArgs> {\n private callbacks: Array<EventHandler<TArgs>> = [];\n\n subscribe(callback: EventHandler<TArgs>): () => void {\n this.callbacks.push(callback);\n\n return () => this.unsubscribe(callback);\n }\n\n dispatch(args: TArgs) {\n const callbacks = this.callbacks.slice(0);\n callbacks.forEach((callback) => {\n callback(args);\n });\n }\n\n unsubscribe(callback: EventHandler<TArgs>) {\n const index = this.callbacks.indexOf(callback);\n if (index > -1) {\n this.callbacks.splice(index, 1);\n }\n }\n\n get subscriberCount() {\n return this.callbacks.length;\n }\n}\n","export const DEFAULT_HEARTBEAT_INTERVAL_MS = 59700;\n\nexport interface HeartbeatListener {\n /**\n * @param playerCurrentTime the current player playback time of the video in seconds.\n */\n onHeartbeat: (playerCurrentTime: number) => void;\n}\n\n/** Get the current player playback time of the video in seconds. */\ntype PlayerCurrentTimeCallback = () => number;\n\nexport class HeartbeatService {\n private heartbeatInterval: ReturnType<typeof setInterval> | undefined;\n private listener: HeartbeatListener | undefined;\n private readonly getPlayerCurrentTime: PlayerCurrentTimeCallback;\n\n constructor(getPlayerCurrentTime: PlayerCurrentTimeCallback) {\n this.getPlayerCurrentTime = getPlayerCurrentTime;\n }\n\n setListener(listener: HeartbeatListener) {\n this.listener = listener;\n }\n\n startHeartbeat() {\n if (this.heartbeatInterval !== undefined) {\n this.clearHeartbeat();\n }\n this.heartbeatInterval = setInterval(() => {\n this.listener?.onHeartbeat(this.getPlayerCurrentTime());\n }, DEFAULT_HEARTBEAT_INTERVAL_MS);\n }\n\n stopHeartbeat() {\n this.clearHeartbeat();\n }\n\n private clearHeartbeat() {\n clearTimeout(this.heartbeatInterval);\n this.heartbeatInterval = undefined;\n }\n}\n","import {ErrorSeverity} from '../types/AnalyticsConfig';\n\n/**\n * This class is used to limit error reporting for identical consecutive error codes and severities per session.\n *\n * Repeated consecutive errors of the same code and severity are limited to {@link IdenticalErrorReportingLimiter.MAX_IDENTICAL_ERROR_REPORTING}.\n */\nexport class IdenticalErrorReportingLimiter {\n /** The maximum number of times the same error code and severity can be reported consecutively. */\n private static MAX_IDENTICAL_ERROR_REPORTING = 5;\n\n private _lastErrorCode: number | undefined;\n private _lastErrorSeverity: ErrorSeverity | undefined;\n private _currentErrorCount = 0;\n\n /**\n * Determines whether an error with the given errorCode and errorSeverity should be reported,\n * based on the limit of identical consecutive error reports.\n *\n * @param errorCode - The error code for which we are checking the reporting conditions.\n * @param errorSeverity - The error severity for which we are checking the reporting conditions.\n * @returns {boolean} - Returns true if the error can be reported, false if it exceeds the limits.\n */\n shouldReportError(errorCode: number, errorSeverity: ErrorSeverity): boolean {\n if (errorCode === this._lastErrorCode && errorSeverity === this._lastErrorSeverity) {\n this._currentErrorCount++;\n return this._currentErrorCount <= IdenticalErrorReportingLimiter.MAX_IDENTICAL_ERROR_REPORTING;\n }\n\n this._lastErrorCode = errorCode;\n this._lastErrorSeverity = errorSeverity;\n this._currentErrorCount = 1;\n return true;\n }\n\n reset() {\n this._lastErrorCode = undefined;\n this._lastErrorSeverity = undefined;\n this._currentErrorCount = 0;\n }\n}\n","import type {DeferredLicenseLoadingAdapterAPI} from '../adapters/internal/DeferredLicenseLoadingAdapterAPI';\nimport type {AdSample} from '../types/AdSample';\nimport type {AuthenticationCallback} from '../types/AuthenticationCallback';\nimport {LicenseCallFunc, LicensingRequest, LicensingResponse, LicensingResult} from '../types/LicensingRequest';\nimport type {Sample} from '../types/Sample';\nimport {logger} from '../utils/Logger';\nimport {ANALYTICS_LICENSECALL_TIMEOUT} from '../utils/Settings';\n\nimport type {Backend} from './Backend';\nimport {NoOpBackend} from './NoOpBackend';\nimport {QueueBackend} from './QueueBackend';\nimport {RemoteBackend} from './RemoteBackend';\n\n/**\n * The `LicenseCheckingBackend` class is responsible for sending license requests\n * and routing samples to the appropriate backend based on the license status.\n *\n * The class manages a queue of samples during the license check process, ensuring that\n * samples are not lost while the license status is being determined. Once the license\n * is validated, the queued samples are flushed to the appropriate backend.\n *\n * @implements {Backend}\n */\nexport class LicenseCheckingBackend implements Backend {\n promise?: Promise<LicensingResponse>;\n private licenseLazyLoadingTimeoutHandle?: ReturnType<typeof setTimeout>;\n private backend: Backend;\n private info: LicensingRequest;\n\n constructor(\n info: LicensingRequest,\n private licenseCall: LicenseCallFunc,\n private backendBaseUrl: string,\n private adapter: DeferredLicenseLoadingAdapterAPI,\n private authenticationCallback: AuthenticationCallback,\n ) {\n this.info = {...info};\n this.backend = new QueueBackend();\n this.licenseCall = licenseCall;\n\n if (info.key !== undefined && info.key !== '') {\n this.promise = this.wrapLicenseCheckPromiseWithCallback(this.performLicenseCheck(), this.authenticationCallback);\n } else if (adapter.supportsDeferredLicenseLoading === true) {\n adapter.onLicenseKeyReceived.subscribe(this.licenseKeyReceived);\n adapter.onLicenseCallFailed.subscribe(this.licenseCallFailed);\n this.licenseLazyLoadingTimeoutHandle = setTimeout(this.licenseLazyLoadingTimeout, ANALYTICS_LICENSECALL_TIMEOUT);\n } else {\n authenticationCallback.authenticationCompleted(false, undefined);\n this.backend = new NoOpBackend();\n }\n }\n\n performLicenseCheck(): Promise<LicensingResponse> {\n const {key, domain, version} = this.info;\n if (!key || key === '') {\n const error: LicensingResponse = {\n status: LicensingResult.Denied,\n message: 'No license key provided',\n };\n this.backend = new NoOpBackend();\n return Promise.resolve(error);\n }\n\n return this.licenseCall(key, domain, version, this.backendBaseUrl)\n .then((result) => {\n if (result.status === LicensingResult.Granted) {\n const remoteBackend = new RemoteBackend(this.backendBaseUrl, key);\n (this.backend as QueueBackend).flushTo(remoteBackend);\n this.backend = remoteBackend;\n } else {\n throw new Error(result.message);\n }\n return result;\n })\n .catch((err: Error) => {\n if (err.message === 'Ignoring Impression due to DNT Header being set') {\n logger.error('License Check for Bitmovin Analytics failed because of', err);\n } else {\n logger.errorMessageToUser('License Check for Bitmovin Analytics failed because of', err);\n }\n this.backend = new NoOpBackend();\n return {\n status: LicensingResult.Denied,\n message: err.message,\n };\n });\n }\n\n sendRequest(sample: Sample): void {\n this.backend.sendRequest(sample);\n }\n sendUnloadRequest(sample: Sample): void {\n this.backend.sendUnloadRequest(sample);\n }\n sendRequestSynchronous(sample: Sample): void {\n this.backend.sendRequestSynchronous(sample);\n }\n sendAdRequest(adSample: AdSample): void {\n this.backend.sendAdRequest(adSample);\n }\n\n private licenseKeyReceived = (eventArgs: {licenseKey: string}) => {\n clearTimeout(this.licenseLazyLoadingTimeoutHandle);\n this.unsubscribeFromAdapter();\n this.info.key = eventArgs.licenseKey;\n this.promise = this.wrapLicenseCheckPromiseWithCallback(this.performLicenseCheck(), this.authenticationCallback);\n };\n\n private licenseCallFailed = () => {\n clearTimeout(this.licenseLazyLoadingTimeoutHandle);\n this.unsubscribeFromAdapter();\n this.backend = new NoOpBackend();\n this.authenticationCallback.authenticationCompleted(false, undefined);\n };\n\n private licenseLazyLoadingTimeout = () => {\n this.unsubscribeFromAdapter();\n this.backend = new NoOpBackend();\n this.authenticationCallback.authenticationCompleted(false, undefined);\n };\n\n private unsubscribeFromAdapter() {\n this.adapter.onLicenseKeyReceived.unsubscribe(this.licenseKeyReceived);\n this.adapter.onLicenseCallFailed.unsubscribe(this.licenseCallFailed);\n }\n\n private wrapLicenseCheckPromiseWithCallback(\n promise: Promise<LicensingResponse>,\n authenticationCallback: AuthenticationCallback,\n ): Promise<LicensingResponse> {\n return promise.then((response) => {\n authenticationCallback.authenticationCompleted(response.status === LicensingResult.Granted, response.features);\n return response;\n });\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\nimport {isNullish} from '../utils/Utils';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `LongPlaytimeFilteringBackend` is a decorator class that filters out samples\n * where the `played` time exceeds a specified threshold.\n *\n * If a sample's `played` time surpasses the threshold, it is not forwarded to the next backend.\n * Otherwise, the sample is passed along to the next backend for further processing.\n *\n * @implements {Backend}\n */\nexport class LongPlaytimeFilteringBackend implements Backend {\n readonly nextBackend: Backend;\n\n constructor(next: Backend) {\n this.nextBackend = next;\n }\n\n sendRequest(sample: Sample): void {\n if (this.isPlayedAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendRequest(sample);\n }\n\n sendUnloadRequest(sample: Sample): void {\n if (this.isPlayedAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendUnloadRequest(sample);\n }\n\n sendRequestSynchronous(sample: Sample): void {\n if (this.isPlayedAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendRequestSynchronous(sample);\n }\n\n sendAdRequest(adSample: AdSample): void {\n this.nextBackend.sendAdRequest(adSample);\n }\n\n private isPlayedAboveThreshold(sample: Sample): boolean {\n return (isNullish(sample.played) ? 0 : sample.played) >= 90000;\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `NoOpBackend` is a no-operation implementation of the `Backend` interface.\n * It serves as a placeholder backend when the actual `Backend` functionality is disabled or not required.\n * E.g. in scenarios such as releasing the adapter or when the Collector is disabled via {@link CollectorConfig#enabled}.\n *\n * Using `NoOpBackend` ensures that the code does not need to handle cases where `Backend` might be undefined,\n * thereby simplifying the logic and reducing the need for null or undefined checks.\n *\n * @implements {Backend}\n */\nexport class NoOpBackend implements Backend {\n sendRequest(_sample: Sample): void {\n // empty\n }\n sendUnloadRequest(_sample: Sample): void {\n // empty\n }\n sendRequestSynchronous(_sample: Sample): void {\n // empty\n }\n sendAdRequest(_adSample: AdSample): void {\n throw new Error('Method not implemented.');\n }\n}\n","import {isFiniteNumber} from '../utils/numberUtils';\nimport * as Settings from '../utils/Settings';\n\nconst INITIAL_VALUE = 0;\n\n/**\n * This service is responsible for deciding whether a quality change event should be sent or not, based on\n * - the quality changes count that has already been sent in a certain timeframe/interval\n * - the previous video and audio bitrate values, to avoid sending the first quality change event or the following\n * events when the bitrate did not change (some players report quality changes with the same bitrate, which should\n * not be tracked)\n * - whether the startup has finished, to avoid sending quality change events for the initial bitrate values\n * that some players report before startup, which can differ from the ones that are used after startup\n */\nexport default class QualityChangeService {\n /** Flag to block quality change events when a certain threshold in a certain timeframe/interval is exceeded */\n private qualityChangeCount = INITIAL_VALUE;\n private qualityChangeCountResetIntervalId: ReturnType<typeof setInterval> | undefined;\n private readonly QUALITY_CHANGE_COUNT_THRESHOLD: number;\n\n /** Flag to block the first (initial) video quality change event or the following events when the bitrate did not change */\n private previousVideoBitrate = INITIAL_VALUE;\n /** Flag to block the first (initial) audio quality change event or the following events when the bitrate did not change */\n private previousAudioBitrate = INITIAL_VALUE;\n\n /** Flag to block quality change events until startup has finished */\n private startupHasFinished = false;\n\n constructor(qualityChangeCountThreshold: number = Settings.ANALYTICS_QUALITY_CHANGE_COUNT_THRESHOLD) {\n this.QUALITY_CHANGE_COUNT_THRESHOLD = qualityChangeCountThreshold;\n }\n\n resetValues() {\n this.qualityChangeCount = INITIAL_VALUE;\n this.stopResetInterval();\n\n this.previousVideoBitrate = INITIAL_VALUE;\n this.previousAudioBitrate = INITIAL_VALUE;\n\n this.startupHasFinished = false;\n }\n\n increaseCounter() {\n this.qualityChangeCount++;\n }\n\n hasExceededQualityChangeThreshold(): boolean {\n return this.qualityChangeCount > this.QUALITY_CHANGE_COUNT_THRESHOLD;\n }\n\n setStartupHasFinished(startupVideoBitrate: number | undefined, startupAudioBitrate: number | undefined): void {\n this.startupHasFinished = true;\n\n // check if the startup video bitrate value is known/defined and valid\n if (isFiniteNumber(startupVideoBitrate)) {\n this.previousVideoBitrate = startupVideoBitrate;\n }\n // check if the startup audio bitrate value is known/defined and valid\n if (isFiniteNumber(startupAudioBitrate)) {\n this.previousAudioBitrate = startupAudioBitrate;\n }\n }\n\n shouldAllowVideoQualityChange(newBitrate: number | undefined): boolean {\n return (\n // if the startup has finished\n this.startupHasFinished &&\n // if the new bitrate value is valid\n isFiniteNumber(newBitrate) &&\n // if the new bitrate is not the first one reported (the initial value is not still set)\n this.previousVideoBitrate !== INITIAL_VALUE &&\n // if the bitrate did change\n this.previousVideoBitrate !== newBitrate &&\n // if the quality change count threshold has not been exceeded\n !this.hasExceededQualityChangeThreshold()\n );\n }\n\n setVideoBitrate(newBitrate: number): void {\n if (this.startupHasFinished) {\n this.previousVideoBitrate = newBitrate;\n }\n }\n\n shouldAllowAudioQualityChange(newBitrate: number | undefined): boolean {\n return (\n // if the startup has finished\n this.startupHasFinished &&\n // if the new bitrate value is valid\n isFiniteNumber(newBitrate) &&\n // if the new bitrate is not the first one reported (the initial value is not still set)\n this.previousAudioBitrate !== INITIAL_VALUE &&\n // if the bitrate did change\n this.previousAudioBitrate !== newBitrate &&\n // if the quality change count threshold has not been exceeded\n !this.hasExceededQualityChangeThreshold()\n );\n }\n\n setAudioBitrate(newBitrate: number): void {\n if (this.startupHasFinished) {\n this.previousAudioBitrate = newBitrate;\n }\n }\n\n startResetInterval() {\n if (this.qualityChangeCountResetIntervalId !== undefined) {\n return;\n }\n\n this.qualityChangeCountResetIntervalId = setInterval(() => {\n this.qualityChangeCount = 0;\n }, Settings.ANALYTICS_QUALITY_CHANGE_COUNT_RESET_INTERVAL);\n }\n\n stopResetInterval() {\n if (this.qualityChangeCountResetIntervalId === undefined) {\n return;\n }\n\n clearInterval(this.qualityChangeCountResetIntervalId);\n delete this.qualityChangeCountResetIntervalId;\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `QueueBackend` class is responsible for queuing samples for deferred processing.\n * Samples are stored in different queues depending on the sample type and can be flushed\n * to another backend for further processing.\n *\n * This is useful e.g. to still collect sample data while waiting for a license call to succeed.\n *\n * @implements {Backend}\n */\nexport class QueueBackend implements Backend {\n private readonly queue: Sample[] = [];\n private readonly unloadQueue: Sample[] = [];\n private readonly syncQueue: Sample[] = [];\n private readonly adQueue: AdSample[] = [];\n\n sendRequest(sample: Sample): void {\n this.queue.push(sample);\n }\n sendUnloadRequest(sample: Sample): void {\n this.unloadQueue.push(sample);\n }\n sendRequestSynchronous(sample: Sample): void {\n this.syncQueue.push(sample);\n }\n sendAdRequest(adSample: AdSample): void {\n this.adQueue.push(adSample);\n }\n\n flushTo(backend: Backend) {\n this.queue.forEach((e) => {\n backend.sendRequest(e);\n });\n this.unloadQueue.forEach((e) => {\n backend.sendUnloadRequest(e);\n });\n this.syncQueue.forEach((e) => {\n backend.sendRequestSynchronous(e);\n });\n this.adQueue.forEach((e) => {\n backend.sendAdRequest(e);\n });\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\nimport {AnalyticsCall} from '../utils/AnalyticsCall';\nimport {noOp} from '../utils/Utils';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `RemoteBackend` class is responsible for actually sending out the samples using the {@link AnalyticsCall} class.\n * Before each sample is sent, the `RemoteBackend` attaches a license key to the sample.\n *\n * @implements {Backend}\n */\nexport class RemoteBackend implements Backend {\n private readonly analyticsCall: AnalyticsCall;\n private readonly licenseKey: string;\n\n constructor(backendBaseUrl: string, licenseKey: string) {\n this.analyticsCall = new AnalyticsCall(backendBaseUrl);\n this.licenseKey = licenseKey;\n }\n\n sendRequest(sample: Sample): void {\n sample.key = this.licenseKey;\n this.analyticsCall.sendRequest(sample, noOp);\n }\n\n sendUnloadRequest(sample: Sample): void {\n sample.key = this.licenseKey;\n this.analyticsCall.sendUnloadRequest(sample);\n }\n\n sendRequestSynchronous(sample: Sample): void {\n sample.key = this.licenseKey;\n this.analyticsCall.sendRequestSynchronous(sample, noOp);\n }\n\n sendAdRequest(adSample: AdSample): void {\n adSample.key = this.licenseKey;\n this.analyticsCall.sendAdRequest(adSample);\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\nimport {SEQUENCE_NUMBER_LIMIT} from '../utils/Settings';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `SequenceNumberBackend` is a decorator class that increments a samples sequence number and filters out samples\n * where the `sequenceNumber` exceeds a specified threshold.\n *\n * If a sample's `sequenceNumber` surpasses the threshold, it is not forwarded to the next backend.\n * Otherwise, the sample is passed along to the next backend for further processing.\n *\n * @implements {Backend}\n */\nexport class SequenceNumberBackend implements Backend {\n readonly nextBackend: Backend;\n sequenceNumber = 0;\n\n constructor(underlying: Backend) {\n this.nextBackend = underlying;\n }\n\n sendRequest(sample: Sample): void {\n this.updateSampleBeforeSending(sample);\n if (this.isSequenceNumberAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendRequest(sample);\n }\n\n sendUnloadRequest(sample: Sample): void {\n this.updateSampleBeforeSending(sample);\n if (this.isSequenceNumberAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendUnloadRequest(sample);\n }\n\n sendRequestSynchronous(sample: Sample): void {\n this.updateSampleBeforeSending(sample);\n if (this.isSequenceNumberAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendRequestSynchronous(sample);\n }\n\n sendAdRequest(adSample: AdSample): void {\n if (this.isSequenceNumberAboveThreshold(adSample)) {\n return;\n }\n this.nextBackend.sendAdRequest(adSample);\n }\n\n private updateSampleBeforeSending(sample: Sample) {\n sample.sequenceNumber = this.sequenceNumber++;\n }\n\n private isSequenceNumberAboveThreshold(sample: Sample): boolean {\n return (sample.sequenceNumber ?? 0) > SEQUENCE_NUMBER_LIMIT;\n }\n}\n","import type {AnalyticsConfig} from '../types/AnalyticsConfig';\nimport {deleteCookie, getCookie, setCookie} from '../utils/documentUtils';\nimport {isNumber} from '../utils/numberUtils';\nimport {isBlank, isValidString} from '../utils/stringUtils';\nimport {isNotNullish, isNullish} from '../utils/Utils';\nimport {generateUUID} from '../utils/uuidUtils';\n\nexport const COOKIE_NAME_BITMOVIN_ANALYTICS_UUID = 'bitmovin_analytics_uuid';\n/** One year in seconds */\nexport const COOKIE_DEFAULT_MAX_AGE = 365 * 24 * 60 * 60;\n\nexport class SessionPersistenceHandler {\n readonly userId: string;\n\n constructor(config: AnalyticsConfig) {\n const collectorConfig = config.config;\n\n const shouldNotUseCookies = collectorConfig?.cookiesEnabled === false;\n\n if (shouldNotUseCookies) {\n deleteCookie(COOKIE_NAME_BITMOVIN_ANALYTICS_UUID);\n this.userId = generateUUID();\n return;\n }\n\n const existingUserId = getCookie(COOKIE_NAME_BITMOVIN_ANALYTICS_UUID);\n this.userId = isNotNullish(existingUserId) && !isBlank(existingUserId) ? existingUserId : generateUUID();\n\n const cookieDomain = validateCookieDomainValue(collectorConfig?.cookiesDomain);\n const cookieMaxAge = validateCookieMaxAgeValue(collectorConfig?.cookiesMaxAge);\n\n // we set also expires, because max-age is not supported on old browsers like IE8\n const nowMillis = Date.now();\n const expirationDate = new Date(nowMillis + cookieMaxAge * 1000);\n const cookieExpires = expirationDate.toUTCString();\n\n setCookie(COOKIE_NAME_BITMOVIN_ANALYTICS_UUID, this.userId, {\n domain: cookieDomain,\n expires: cookieExpires,\n maxAge: cookieMaxAge,\n });\n }\n}\n\nexport const validateCookieDomainValue = (value: unknown): string | undefined => {\n if (isNullish(value)) {\n return undefined;\n }\n\n if (!isValidString(value)) {\n return undefined;\n }\n\n if (isBlank(value)) {\n return undefined;\n }\n\n return encodeURIComponent(value);\n};\n\nexport const validateCookieMaxAgeValue = (value: unknown): number => {\n if (isNullish(value)) {\n return COOKIE_DEFAULT_MAX_AGE;\n }\n\n if (!isNumber(value)) {\n return COOKIE_DEFAULT_MAX_AGE;\n }\n\n return value;\n};\n","import type {CodecInfo} from '../types/CodecInfo';\nimport type {PlaybackInfo} from '../types/PlaybackInfo';\nimport {isBlank} from '../utils/stringUtils';\nimport {isNotNullish} from '../utils/Utils';\n\n/**\n * This class is used to store source specific information for the player\n * mainly as a fallback if sourceInfo cannot be determined by the player since the source is already unloaded\n */\nexport class SourceInfoFallbackService {\n private streamFormat: PlaybackInfo['streamFormat'];\n private audioCodec: PlaybackInfo['audioCodec'];\n private videoCodec: PlaybackInfo['videoCodec'];\n\n reset() {\n this.streamFormat = undefined;\n this.audioCodec = undefined;\n this.videoCodec = undefined;\n }\n\n setStreamFormat(streamFormat: PlaybackInfo['streamFormat']) {\n this.streamFormat = streamFormat;\n }\n\n applyStreamFormat(playbackInfo: PlaybackInfo) {\n if (isBlank(this.streamFormat)) {\n return;\n }\n playbackInfo.streamFormat = this.streamFormat;\n }\n\n /**\n * Apply fallback values to {@link PlaybackInfo} if available.\n * If provided {@link CodecInfo} values are available, we store them as new fallback values, before we apply them.\n */\n applyAndStoreCodecInfo(playbackInfo: PlaybackInfo, codecInfo: CodecInfo | undefined) {\n if (isNotNullish(codecInfo?.audioCodec)) {\n this.audioCodec = codecInfo.audioCodec;\n }\n if (isNotNullish(codecInfo?.videoCodec)) {\n this.videoCodec = codecInfo.videoCodec;\n }\n\n if (!isBlank(this.audioCodec)) {\n playbackInfo.audioCodec = this.audioCodec;\n }\n if (!isBlank(this.videoCodec)) {\n playbackInfo.videoCodec = this.videoCodec;\n }\n }\n}\n","import type {SsaiAdBreakMetadata, SsaiAdMetadata, SsaiAdQuartile, SsaiAdQuartileMetadata} from '../../api/AdapterAPI';\nimport {AD_TYPE} from '../../enums/AdType';\nimport {ErrorCode} from '../../enums/ErrorCode';\nimport {AnalyticsError} from '../../types/AnalyticsConfig';\nimport {customDataValuesKeys} from '../../types/CustomDataValues';\nimport type {Sample} from '../../types/Sample';\nimport {isNotNullish} from '../../utils/Utils';\nimport {generateUUID} from '../../utils/uuidUtils';\n\nimport type {InternalSsaiMetadata, SsaiEngagementInteractionData} from './ssaiEngagementInteractionData';\nimport {\n getCurrentMonotonicTimestampInMs,\n getMonotonicTimestampInMsSince,\n SSAI_RELATED_SAMPLE_MARKER,\n} from './ssaiUtils';\n\nexport type SsaiEventHandler = {\n getPlayerCurrentTime: () => number;\n reportEngagementInteraction: (data: SsaiEngagementInteractionData) => void;\n reportPlaybackInteraction: (timestamp: number, playerCurrentTime: number) => void;\n};\n\nenum SsaiState {\n AD_BREAK_STARTED,\n ACTIVE,\n IDLE,\n}\n\n// we start with -1, to be able to increment it before sending the first sample\n// this way the current adIndex is the one of the current playing ad\nconst INITIAL_AD_INDEX_VALUE = -1;\n\nexport class SsaiService {\n /** if `undefined` then service is not active and should not do anything, why: initially we activate it only for Bitmovin8 */\n private eventHandler: SsaiEventHandler | undefined = undefined;\n\n /** Index of the current ad in the whole session */\n private adIndex: number = INITIAL_AD_INDEX_VALUE;\n\n private state: SsaiState = SsaiState.IDLE;\n private isFirstSampleOfAd = false;\n /**\n * represents the current playing ad metadata\n * is `undefined` when no ad is playing (after endAdBreak)\n * or omitted by customer\n */\n private currentAdMetadata: InternalSsaiMetadata | undefined;\n\n /**\n * The impression id for the currently playing ad\n * is undefined when no ad is playing\n */\n private currentAdImpressionId: string | undefined;\n\n /** List of quartiles already sent for the current ad */\n private sentAdQuartiles: SsaiAdQuartile[] = [];\n\n /**\n * Flags whether an error was sent during an ad to avoid sending multiple errors for one ad,\n * which would skew e.g. the ad abandonment rate.\n */\n private errorSent: boolean = false;\n\n /**\n * The timestamp marking when the `adStart` method was called.\n * This timestamp is used to calculate the time difference between the `adStart` call\n * and subsequent `adQuartileFinished` or `sendAdEngagementErrorSample` calls.\n */\n private timestampOfAdStart: number | undefined;\n\n activate(eventHandler: SsaiEventHandler) {\n this.eventHandler = eventHandler;\n }\n\n adBreakStart(adBreakMetadata?: SsaiAdBreakMetadata) {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state != SsaiState.IDLE) {\n return;\n }\n\n this.state = SsaiState.AD_BREAK_STARTED;\n this.currentAdMetadata = {\n ...adBreakMetadata,\n };\n }\n\n adStart(adMetadata?: SsaiAdMetadata) {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state == SsaiState.IDLE) {\n return;\n }\n\n const timestamp = new Date().getTime();\n const playerCurrentTime = this.eventHandler.getPlayerCurrentTime();\n\n // report playback sample - will be saved in our playback related data lake\n // - with the first adStart call we need to close the current normal playback sample (no ssai ad information yet because SsaiState is not yet set to active)\n // - with all following adStart calls, we will deliver previous ssai ad information (SsaiState is already set to active)\n this.eventHandler.reportPlaybackInteraction(timestamp, playerCurrentTime);\n\n this.state = SsaiState.ACTIVE;\n // to include the adIndex in the next sample which will be the first sample of this started ad\n this.isFirstSampleOfAd = true;\n this.adIndex++;\n\n this.resetAdData();\n\n this.currentAdMetadata = {\n adPosition: this.currentAdMetadata?.adPosition,\n adId: adMetadata?.adId,\n adSystem: adMetadata?.adSystem,\n customData: adMetadata?.customData,\n };\n\n this.currentAdImpressionId = generateUUID();\n this.timestampOfAdStart = getCurrentMonotonicTimestampInMs();\n\n // report engagement sample - will be saved in our ad related data lake\n this.eventHandler.reportEngagementInteraction({\n type: 'started',\n adIndex: this.adIndex,\n currentAdImpressionId: this.currentAdImpressionId,\n currentAdMetadata: isNotNullish(this.currentAdMetadata) ? this.currentAdMetadata : {},\n });\n }\n\n adQuartileFinished(adQuartile: SsaiAdQuartile, adQuartileMetadata: SsaiAdQuartileMetadata) {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not activated\n return;\n }\n\n if (this.state != SsaiState.ACTIVE) {\n return;\n }\n\n if (this.sentAdQuartiles.includes(adQuartile)) {\n //do nothing if adQuartile was already sent\n return;\n }\n\n this.eventHandler.reportEngagementInteraction({\n type: 'quartile',\n adIndex: this.adIndex,\n currentAdImpressionId: this.currentAdImpressionId!,\n currentAdMetadata: isNotNullish(this.currentAdMetadata) ? this.currentAdMetadata : {},\n quartile: adQuartile,\n quartileMetadata: adQuartileMetadata,\n timeSinceAdStartedInMs: getMonotonicTimestampInMsSince(this.timestampOfAdStart),\n });\n this.sentAdQuartiles.push(adQuartile);\n }\n\n adBreakEnd() {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state == SsaiState.IDLE) {\n return;\n }\n\n if (this.state == SsaiState.ACTIVE) {\n const timestamp = new Date().getTime();\n const playerCurrentTime = this.eventHandler.getPlayerCurrentTime();\n this.eventHandler.reportPlaybackInteraction(timestamp, playerCurrentTime);\n }\n\n this.resetAdBreakData();\n }\n\n manipulate(sample: Sample): void {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state != SsaiState.ACTIVE) {\n return;\n }\n\n sample.ad = AD_TYPE.SSAI;\n sample.adId = this.currentAdMetadata?.adId;\n sample.adSystem = this.currentAdMetadata?.adSystem;\n sample.adPosition = this.currentAdMetadata?.adPosition;\n // we only mark the first sample of an ssai ad with the index in the playback/audience data (non ad table)\n // this allows us to count the number of ads\n if (this.isFirstSampleOfAd) {\n sample.adIndex = this.adIndex;\n this.isFirstSampleOfAd = false;\n }\n\n const customData = this.currentAdMetadata?.customData;\n if (isNotNullish(customData)) {\n customDataValuesKeys.forEach((key) => {\n if (customData[key]) {\n sample[key] = customData[key];\n }\n });\n }\n\n sample[SSAI_RELATED_SAMPLE_MARKER] = true; // mark it as ssai sample\n }\n\n sendAdEngagementErrorSample(error: AnalyticsError, originalError: any) {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state !== SsaiState.ACTIVE) {\n return;\n }\n\n // only send one error sample per ad\n if (this.errorSent) {\n return;\n }\n\n // This error code is related to the Analytics product and is non-fatal.\n // It is not triggered by the Player and does not interrupt or affect playback,\n // so there is no need to report an ad error sample.\n if (error.code === ErrorCode.QUALITY_CHANGE_THRESHOLD_EXCEEDED.code) {\n return;\n }\n\n this.eventHandler.reportEngagementInteraction({\n type: 'error',\n adIndex: this.adIndex,\n currentAdImpressionId: this.currentAdImpressionId!,\n currentAdMetadata: isNotNullish(this.currentAdMetadata) ? this.currentAdMetadata : {},\n analyticsError: error,\n originalError: originalError,\n timeSinceAdStartedInMs: getMonotonicTimestampInMsSince(this.timestampOfAdStart),\n });\n this.errorSent = true;\n }\n\n isInActiveState(): boolean {\n return this.state === SsaiState.ACTIVE;\n }\n\n resetSourceRelatedState() {\n this.resetAdBreakData();\n this.adIndex = INITIAL_AD_INDEX_VALUE;\n }\n\n private resetAdBreakData() {\n this.state = SsaiState.IDLE;\n this.isFirstSampleOfAd = false;\n delete this.currentAdMetadata;\n this.resetAdData();\n }\n\n private resetAdData() {\n delete this.currentAdMetadata?.customData;\n delete this.currentAdMetadata?.adId;\n delete this.currentAdMetadata?.adSystem;\n this.errorSent = false;\n this.currentAdImpressionId = undefined;\n this.sentAdQuartiles = [];\n this.timestampOfAdStart = undefined;\n }\n}\n\nfunction isActivated(eventHandler: SsaiEventHandler | undefined): eventHandler is SsaiEventHandler {\n return isNotNullish(eventHandler);\n}\n","import {SsaiAdBreakMetadata, SsaiAdMetadata, SsaiAdQuartile, SsaiAdQuartileMetadata} from '../../api/AdapterAPI';\nimport {AnalyticsError} from '../../types/AnalyticsConfig';\n\nexport type InternalSsaiMetadata = SsaiAdBreakMetadata & SsaiAdMetadata;\n\ntype SsaiEngagementBaseData = {\n adIndex: number;\n currentAdImpressionId: string;\n currentAdMetadata: InternalSsaiMetadata;\n type: 'error' | 'quartile' | 'started';\n};\n\nexport type SsaiEngagementErrorData = SsaiEngagementBaseData & {\n analyticsError: AnalyticsError;\n originalError?: any;\n timeSinceAdStartedInMs: number | undefined;\n type: 'error';\n};\n\nexport function isSsaiEngagementErrorData(data: SsaiEngagementInteractionData): data is SsaiEngagementErrorData {\n return data.type === 'error';\n}\n\nexport type SsaiEngagementQuartileData = SsaiEngagementBaseData & {\n quartile: SsaiAdQuartile;\n quartileMetadata: SsaiAdQuartileMetadata;\n timeSinceAdStartedInMs: number | undefined;\n type: 'quartile';\n};\n\nexport function isSsaiEngagementQuartileData(data: SsaiEngagementInteractionData): data is SsaiEngagementQuartileData {\n return data.type === 'quartile';\n}\n\nexport type SsaiEngagementStartedData = SsaiEngagementBaseData & {type: 'started'};\n\nexport function isSsaiEngagementStartedData(data: SsaiEngagementInteractionData): data is SsaiEngagementStartedData {\n return data.type === 'started';\n}\n\nexport type SsaiEngagementInteractionData =\n | SsaiEngagementErrorData\n | SsaiEngagementQuartileData\n | SsaiEngagementStartedData;\n","import type {SsaiAdQuartile, SsaiAdQuartileMetadata} from '../../api/AdapterAPI';\nimport type {AdSample} from '../../types/AdSample';\nimport {ErrorSeverity} from '../../types/AnalyticsConfig';\nimport {customDataValuesKeys} from '../../types/CustomDataValues';\nimport type {Sample} from '../../types/Sample';\nimport {getGlobalPerformanceNow} from '../../utils/globalScopeUtils';\nimport {isNotNullish, isNullish} from '../../utils/Utils';\n\nimport type {\n InternalSsaiMetadata,\n SsaiEngagementErrorData,\n SsaiEngagementQuartileData,\n SsaiEngagementStartedData,\n} from './ssaiEngagementInteractionData';\n\n/**\n * Ssai marker property for {@link Sample} to indicate that this is \"ssai related sample\" and can cause the spike\n * on ingress side. It will be picked up in `AnalyticsCall` and used to send that \"ssai related sample\" as request\n * with ssai redirection. @see {@link ROUTING_URL_PARAM}\n *\n * What is \"ssai related sample\" ?\n * - \"last sample\" that was triggered to be sent, because of coming SSAI interaction, the SSAI ad break start (WITHOUT `sample.ad = 2`),\n * because it causes also the spike as all viewers are received same SSAI at the same time.\n * - all following samples, triggered by SSAI interaction while SSAI ad break is running (now WITH `sample.ad = 2`)\n *\n * We don't we need it with {@link AdSample} too?\n * Because all \"ssai related ad samples\" are triggered only during ssai ad break, so all have already\n * {@link AdSample#adType} property set and we can relay on that in `AnalyticsCall` to send them with ssai redirection.\n */\nexport const SSAI_RELATED_SAMPLE_MARKER = 'triggeredBySsai';\n\nexport function isSsaiRelatedSample(sample: AdSample | Sample): boolean {\n if (sample[SSAI_RELATED_SAMPLE_MARKER]) {\n delete sample[SSAI_RELATED_SAMPLE_MARKER]; // clean up the marker property that should not be present on the sample property\n return true;\n } else if ((sample as AdSample).adType === 2) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Due to ssai being spiky by design, we should mark all analytics requests (with samples / ad samples)\n * that are ssai related, with a specific URL parameter. The load balancer can then route traffic according to the URL\n * parameter to a different ingress instance, which gives us more flexibility when ssai spikes are coming in.\n */\nexport const ROUTING_URL_PARAM = 'routingParam';\nexport const ROUTING_URL_PARAM_VALUE_SSAI = 'ssai';\n\nexport function appendSsaiRoutingParam(url: string): string {\n return `${url}?${ROUTING_URL_PARAM}=${ROUTING_URL_PARAM_VALUE_SSAI}`;\n}\n\nfunction createAdSampleFromSample(sample: Sample): AdSample {\n return {\n audioBitrate: sample?.audioBitrate,\n analyticsVersion: sample?.analyticsVersion,\n adPlaybackHeight: sample?.videoPlaybackHeight,\n adPlaybackWidth: sample?.videoPlaybackWidth,\n cdnProvider: sample?.cdnProvider,\n customData1: sample?.customData1,\n customData2: sample?.customData2,\n customData3: sample?.customData3,\n customData4: sample?.customData4,\n customData5: sample?.customData5,\n customData6: sample?.customData6,\n customData7: sample?.customData7,\n customData8: sample?.customData8,\n customData9: sample?.customData9,\n customData10: sample?.customData10,\n customData11: sample?.customData11,\n customData12: sample?.customData12,\n customData13: sample?.customData13,\n customData14: sample?.customData14,\n customData15: sample?.customData15,\n customData16: sample?.customData16,\n customData17: sample?.customData17,\n customData18: sample?.customData18,\n customData19: sample?.customData19,\n customData20: sample?.customData20,\n customData21: sample?.customData21,\n customData22: sample?.customData22,\n customData23: sample?.customData23,\n customData24: sample?.customData24,\n customData25: sample?.customData25,\n customData26: sample?.customData26,\n customData27: sample?.customData27,\n customData28: sample?.customData28,\n customData29: sample?.customData29,\n customData30: sample?.customData30,\n customData31: sample?.customData31,\n customData32: sample?.customData32,\n customData33: sample?.customData33,\n customData34: sample?.customData34,\n customData35: sample?.customData35,\n customData36: sample?.customData36,\n customData37: sample?.customData37,\n customData38: sample?.customData38,\n customData39: sample?.customData39,\n customData40: sample?.customData40,\n customData41: sample?.customData41,\n customData42: sample?.customData42,\n customData43: sample?.customData43,\n customData44: sample?.customData44,\n customData45: sample?.customData45,\n customData46: sample?.customData46,\n customData47: sample?.customData47,\n customData48: sample?.customData48,\n customData49: sample?.customData49,\n customData50: sample?.customData50,\n customData51: sample?.customData51,\n customData52: sample?.customData52,\n customData53: sample?.customData53,\n customData54: sample?.customData54,\n customData55: sample?.customData55,\n customData56: sample?.customData56,\n customData57: sample?.customData57,\n customData58: sample?.customData58,\n customData59: sample?.customData59,\n customData60: sample?.customData60,\n customData61: sample?.customData61,\n customData62: sample?.customData62,\n customData63: sample?.customData63,\n customData64: sample?.customData64,\n customData65: sample?.customData65,\n customData66: sample?.customData66,\n customData67: sample?.customData67,\n customData68: sample?.customData68,\n customData69: sample?.customData69,\n customData70: sample?.customData70,\n customData71: sample?.customData71,\n customData72: sample?.customData72,\n customData73: sample?.customData73,\n customData74: sample?.customData74,\n customData75: sample?.customData75,\n customData76: sample?.customData76,\n customData77: sample?.customData77,\n customData78: sample?.customData78,\n customData79: sample?.customData79,\n customData80: sample?.customData80,\n customData81: sample?.customData81,\n customData82: sample?.customData82,\n customData83: sample?.customData83,\n customData84: sample?.customData84,\n customData85: sample?.customData85,\n customData86: sample?.customData86,\n customData87: sample?.customData87,\n customData88: sample?.customData88,\n customData89: sample?.customData89,\n customData90: sample?.customData90,\n customData91: sample?.customData91,\n customData92: sample?.customData92,\n customData93: sample?.customData93,\n customData94: sample?.customData94,\n customData95: sample?.customData95,\n customData96: sample?.customData96,\n customData97: sample?.customData97,\n customData98: sample?.customData98,\n customData99: sample?.customData99,\n customData100: sample?.customData100,\n customUserId: sample?.customUserId,\n domain: sample?.domain,\n experimentName: sample?.experimentName,\n key: sample?.key,\n language: sample?.language,\n path: sample?.path,\n platform: sample?.platform,\n player: sample?.player,\n playerKey: sample?.playerKey,\n playerTech: sample?.playerTech,\n size: sample?.size,\n screenHeight: sample?.screenHeight,\n screenWidth: sample?.screenWidth,\n streamFormat: sample?.streamFormat,\n userAgent: sample?.userAgent,\n userId: sample?.userId,\n version: sample?.version,\n videoBitrate: sample?.videoBitrate,\n videoId: sample?.videoId,\n videoImpressionId: sample?.impressionId,\n videoTitle: sample?.videoTitle,\n videoWindowHeight: sample?.videoWindowHeight,\n videoWindowWidth: sample?.videoWindowWidth,\n };\n}\n\nexport function createErrorAdSample(\n playbackSample: Sample,\n ssaiEngagementErrorData: SsaiEngagementErrorData,\n): AdSample {\n return buildAdSample({\n playbackSample,\n currentAdImpressionId: ssaiEngagementErrorData.currentAdImpressionId,\n adIndex: ssaiEngagementErrorData.adIndex,\n currentAdMetadata: ssaiEngagementErrorData.currentAdMetadata,\n quartile: undefined,\n quartileMetadata: undefined,\n errorCode: ssaiEngagementErrorData.analyticsError.code,\n errorMessage: ssaiEngagementErrorData.analyticsError.message,\n errorSeverity: ssaiEngagementErrorData.analyticsError.severity,\n timeSinceAdStartedInMs: ssaiEngagementErrorData.timeSinceAdStartedInMs,\n });\n}\n\nexport function createStartedAdSample(\n playbackSample: Sample,\n ssaiEngagementStartedData: SsaiEngagementStartedData,\n): AdSample {\n return buildAdSample({\n playbackSample,\n currentAdImpressionId: ssaiEngagementStartedData.currentAdImpressionId,\n adIndex: ssaiEngagementStartedData.adIndex,\n currentAdMetadata: ssaiEngagementStartedData.currentAdMetadata,\n quartile: 'started',\n quartileMetadata: undefined,\n errorCode: undefined,\n errorMessage: undefined,\n errorSeverity: undefined,\n timeSinceAdStartedInMs: undefined,\n });\n}\n\nexport function createQuartileAdSample(\n playbackSample: Sample,\n ssaiEngagementQuartileData: SsaiEngagementQuartileData,\n): AdSample {\n return buildAdSample({\n playbackSample,\n currentAdImpressionId: ssaiEngagementQuartileData.currentAdImpressionId,\n adIndex: ssaiEngagementQuartileData.adIndex,\n currentAdMetadata: ssaiEngagementQuartileData.currentAdMetadata,\n quartile: ssaiEngagementQuartileData.quartile,\n quartileMetadata: ssaiEngagementQuartileData.quartileMetadata,\n timeSinceAdStartedInMs: ssaiEngagementQuartileData.timeSinceAdStartedInMs,\n errorCode: undefined,\n errorMessage: undefined,\n errorSeverity: undefined,\n });\n}\n\nfunction buildAdSample({\n playbackSample,\n currentAdImpressionId,\n adIndex,\n currentAdMetadata,\n quartile,\n quartileMetadata,\n errorCode,\n errorMessage,\n errorSeverity,\n timeSinceAdStartedInMs,\n}: {\n adIndex: number;\n currentAdImpressionId: string;\n currentAdMetadata: InternalSsaiMetadata;\n errorCode: number | undefined;\n errorMessage: string | undefined;\n errorSeverity: ErrorSeverity | undefined;\n playbackSample: Sample;\n quartile: 'started' | SsaiAdQuartile | undefined;\n quartileMetadata: SsaiAdQuartileMetadata | undefined;\n timeSinceAdStartedInMs: number | undefined;\n}): AdSample {\n const adEngagementSample: AdSample = {\n ...createAdSampleFromSample(playbackSample),\n adId: currentAdMetadata?.adId,\n adImpressionId: currentAdImpressionId,\n adIndex: adIndex,\n adPosition: currentAdMetadata?.adPosition,\n adSystem: currentAdMetadata?.adSystem,\n adType: 2,\n errorCode: errorCode,\n errorMessage: errorMessage,\n errorSeverity: errorSeverity,\n time: Date.now(),\n timeSinceAdStartedInMs: timeSinceAdStartedInMs,\n };\n\n // set quartile data\n switch (quartile) {\n case 'started':\n adEngagementSample.started = 1;\n break;\n case 'first':\n adEngagementSample.quartile1 = 1;\n adEngagementSample.quartile1FailedBeaconUrl = quartileMetadata?.failedBeaconUrl;\n break;\n case 'midpoint':\n adEngagementSample.midpoint = 1;\n adEngagementSample.midpointFailedBeaconUrl = quartileMetadata?.failedBeaconUrl;\n break;\n case 'third':\n adEngagementSample.quartile3 = 1;\n adEngagementSample.quartile3FailedBeaconUrl = quartileMetadata?.failedBeaconUrl;\n break;\n case 'completed':\n adEngagementSample.completed = 1;\n adEngagementSample.completedFailedBeaconUrl = quartileMetadata?.failedBeaconUrl;\n break;\n }\n\n // set ssai customData\n const customData = currentAdMetadata?.customData;\n if (isNotNullish(customData)) {\n customDataValuesKeys.forEach((key) => {\n if (customData[key]) {\n adEngagementSample[key] = customData[key];\n }\n });\n }\n\n return adEngagementSample;\n}\n\n/**\n * Returns the current timestamp in milliseconds using the `performance.now()` method if available\n * to ensure monotonic timestamps; otherwise, it falls back to using `Date.now()`.\n *\n * Date.now() is dependent on the system clock and not monotonic, it may have been impacted by system\n * and user clock adjustments. The performance.now() method is relative to the timeOrigin property\n * which is a monotonic clock: its current time never decreases and isn't subject to adjustments.\n */\nexport function getCurrentMonotonicTimestampInMs(): number {\n const performanceNow = getGlobalPerformanceNow();\n if (isNullish(performanceNow)) {\n return Date.now();\n }\n\n // floor to return integer value (not double as performance.now() returns)\n return Math.floor(performanceNow);\n}\n\nexport function getMonotonicTimestampInMsSince(timestampInMs: number | undefined): number | undefined {\n if (isNullish(timestampInMs)) {\n return undefined;\n }\n\n return getCurrentMonotonicTimestampInMs() - timestampInMs;\n}\n","export enum AD_TYPE {\n NO_AD = 0,\n CSAI = 1,\n SSAI = 2,\n}\n","export enum CdnProvider {\n AKAMAI = 'akamai',\n BITGRAVITY = 'bitgravity',\n CHINACACHE = 'chinacache',\n CLOUDFLARE = 'cloudflare',\n CLOUDFRONT = 'cloudfront',\n FASTLY = 'fastly',\n MAXCDN = 'maxcdn',\n}\n","import {ErrorSeverity} from '../types/AnalyticsConfig';\n\nexport class ErrorCode {\n static BITMOVIN_PLAYER_LICENSING_ERROR = new ErrorCode(1103, '');\n static SETUP_MISSING_LICENSE_WHITELIST = new ErrorCode(1105, '');\n static QUALITY_CHANGE_THRESHOLD_EXCEEDED = new ErrorCode(\n 10000,\n 'ANALYTICS_QUALITY_CHANGE_THRESHOLD_EXCEEDED',\n 'INFO',\n );\n static BUFFERING_TIMEOUT_REACHED = new ErrorCode(10001, 'ANALYTICS_BUFFERING_TIMEOUT_REACHED');\n static VIDEO_STARTUP_TIMEOUT_REACHED = new ErrorCode(10002, 'ANALYTICS_VIDEOSTART_TIMEOUT_REACHED');\n\n private constructor(\n readonly code: number,\n readonly message: string,\n readonly errorSeverity: ErrorSeverity = 'CRITICAL',\n ) {}\n}\n","import type {\n AnalyticsEventBase,\n CustomDataValuesEvent,\n ErrorEvent,\n QualityChangeEvent,\n SourceChangeEvent,\n} from '../types/EventData';\n\n/**\n * If we specify the name of our initial state, then an implicit 'startup' initial event will be created by JSM\n * and fired when the state machine is constructed.\n *\n * Because that implicit JSM initial event is called 'startup', it could cause confusion with our \"STARTUP state\", so for\n * that reason we will use custom JSM initial event name, to be able to distinguish it from our other {@link Event}s.\n *\n * This event should not be used in the application code, it is only used by the JSM library!\n *\n * @see https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#initialization-options\n */\nexport const JSM_INITIAL_EVENT = 'jsm-initial';\n\nexport enum Event {\n AUDIO_CHANGE = 'audioChange',\n AUDIOTRACK_CHANGED = 'audioTrackChanged',\n CUSTOM_DATA_CHANGE = 'customDataChange',\n /**\n * Fired when the player has finished playback.\n */\n END = 'end',\n END_AD = 'adEnd',\n END_BUFFERING = 'endBuffering',\n END_CAST = 'endCasting',\n END_FULLSCREEN = 'endFullscreen',\n ERROR = 'playerError',\n /**\n * Custom Event fired by Analytics State Machine. Used to immediately transition out of the QUALITY_CHANGE State\n * back to PLAYING State where the quality change was tracked.\n */\n FINISH_QUALITY_CHANGE = 'finishQualityChange',\n /**\n * Manually fired when a source load with autoplay is detected.\n * Required for accurate VST (video startup time) measurement: Some players delay sending PLAY events until\n * manifest/content is loaded, making VST unreliable if calculated from player events alone.\n * For autoplay scenarios, VST is measured as the time from source load to the first\n * PLAYING or TIMEUPDATE event from the player.\n */\n LOADSTART_AUTOPLAY = 'loadstartAutoplay',\n MANUAL_SOURCE_CHANGE = 'manualSourceChangeInitiated',\n MUTE = 'mute',\n PAUSE = 'pause',\n PLAY = 'play',\n PLAYING = 'playing',\n /**\n * Fired when the player is ready to play.\n */\n READY = 'ready',\n SCREEN_RESIZE = 'resize',\n SEEK = 'seek',\n SEEKED = 'seeked',\n SOURCE_LOADED = 'sourceLoaded',\n SOURCE_UNLOADED = 'sourceUnloaded',\n START_AD = 'adStart',\n START_BUFFERING = 'startBuffering',\n START_CAST = 'startCasting',\n START_FULLSCREEN = 'startFullscreen',\n SUBTITLE_CHANGE = 'subtitleChange',\n TIMECHANGED = 'timechanged',\n UN_MUTE = 'unMute',\n /**\n * Fired when page with player is closed or when the player is unloaded/destroyed.\n */\n UNLOAD = 'unload',\n VIDEO_CHANGE = 'videoChange',\n VIDEOSTART_TIMEOUT = 'VIDEOSTART_TIMEOUT',\n}\n\nexport interface EventMap {\n [Event.READY]: AnalyticsEventBase;\n [Event.SOURCE_LOADED]: AnalyticsEventBase;\n [Event.PLAY]: AnalyticsEventBase;\n [Event.PLAYING]: AnalyticsEventBase | CustomDataValuesEvent;\n [Event.PAUSE]: AnalyticsEventBase | CustomDataValuesEvent;\n [Event.TIMECHANGED]: AnalyticsEventBase;\n [Event.SEEK]: AnalyticsEventBase;\n [Event.SEEKED]: AnalyticsEventBase;\n [Event.START_CAST]: AnalyticsEventBase;\n [Event.END_CAST]: AnalyticsEventBase;\n [Event.START_BUFFERING]: AnalyticsEventBase;\n [Event.END_BUFFERING]: AnalyticsEventBase;\n [Event.AUDIOTRACK_CHANGED]: AnalyticsEventBase;\n [Event.AUDIO_CHANGE]: QualityChangeEvent;\n [Event.VIDEO_CHANGE]: QualityChangeEvent;\n [Event.FINISH_QUALITY_CHANGE]: AnalyticsEventBase;\n [Event.START_FULLSCREEN]: AnalyticsEventBase;\n [Event.END_FULLSCREEN]: AnalyticsEventBase;\n [Event.START_AD]: AnalyticsEventBase;\n [Event.SUBTITLE_CHANGE]: AnalyticsEventBase;\n [Event.END_AD]: AnalyticsEventBase;\n [Event.MUTE]: AnalyticsEventBase;\n [Event.UN_MUTE]: AnalyticsEventBase;\n [Event.ERROR]: ErrorEvent;\n [Event.SCREEN_RESIZE]: AnalyticsEventBase;\n [Event.UNLOAD]: AnalyticsEventBase;\n [Event.END]: AnalyticsEventBase;\n [Event.SOURCE_UNLOADED]: AnalyticsEventBase;\n [Event.MANUAL_SOURCE_CHANGE]: SourceChangeEvent;\n [Event.VIDEOSTART_TIMEOUT]: AnalyticsEventBase;\n [Event.CUSTOM_DATA_CHANGE]: AnalyticsEventBase;\n [Event.LOADSTART_AUTOPLAY]: AnalyticsEventBase;\n}\n","import {endsWith} from '../utils/stringUtils';\n\nexport const MIMETypes = {\n MP4: 'video/mp4',\n WEBM: 'video/webm',\n HLS: 'application/x-mpegURL',\n DASH: 'application/dash+xml',\n} as const;\n\n/**\n * @deprecated use {@link getStreamTypesFromURL} directly, when we want to detect {@link StreamTypes} from URL\n *\n * @remarks\n *\n * In our current code, it is visible that detection of MIME Type is only used as \"an additional step\" between\n * stream URL and stream type:\n * - we parse stream URL to detect MIME type\n * - we parse the detected MIME type to get a stream type\n *\n * Because we are not sending the detected MIME type in sample and because we can get {@link StreamTypes} directly from\n * stream URL, we should stop using this MIME type detection code.\n */\nexport function getMIMETypeFromFileExtension(url: string): string | undefined {\n const urlPath = url.split(/[?#]/)[0].toLowerCase();\n\n if (endsWith(urlPath, '.m3u8')) {\n return MIMETypes.HLS;\n }\n if (endsWith(urlPath, '.mp4') || endsWith(urlPath, '.m4v') || endsWith(urlPath, '.m4a')) {\n return MIMETypes.MP4;\n }\n if (endsWith(urlPath, '.webm')) {\n return MIMETypes.WEBM;\n }\n if (endsWith(urlPath, '.mpd')) {\n return MIMETypes.DASH;\n }\n\n return undefined;\n}\n","export enum PAGE_LOAD_TYPE {\n FOREGROUND = 1,\n BACKGROUND = 2,\n}\n","export enum Player {\n BITMOVIN = 'bitmovin',\n BITMOVIN_PWX = 'bitmovin-pwx',\n CHROMECAST_SHAKA = 'chromecast-shaka',\n HLSJS = 'hlsjs',\n HTML5 = 'html5',\n JW = 'jw',\n RADIANT = 'radiant',\n SHAKA = 'shaka',\n THEOPLAYER = 'theoplayer',\n VIDEOJS = 'videojs',\n}\n","export enum PlayerSize {\n Fullscreen = 'FULLSCREEN',\n Window = 'WINDOW',\n}\n","import {endsWith, isBlank} from '../utils/stringUtils';\nimport {isNullish} from '../utils/Utils';\n\nimport {MIMETypes} from './MIMETypes';\n\nexport enum StreamTypes {\n dash = 'dash',\n hls = 'hls',\n prog = 'progressive',\n}\n\nexport function getStreamTypesFromURL(url: string | undefined): StreamTypes | undefined {\n if (isNullish(url) || isBlank(url)) {\n return undefined;\n }\n\n const urlPath = url.split(/[?#]/)[0].toLowerCase();\n\n if (endsWith(urlPath, '.m3u8')) {\n return StreamTypes.hls;\n }\n if (endsWith(urlPath, '.mp4') || endsWith(urlPath, '.m4v') || endsWith(urlPath, '.m4a')) {\n return StreamTypes.prog;\n }\n if (endsWith(urlPath, '.webm')) {\n return StreamTypes.prog;\n }\n if (endsWith(urlPath, '.mpd')) {\n return StreamTypes.dash;\n }\n\n return undefined;\n}\n\nexport function getStreamTypeFromMIMEType(mimeType: string): StreamTypes | undefined {\n const MIME_TYPE_TO_STREAM_TYPE_MAP = {\n [MIMETypes.MP4]: StreamTypes.prog,\n [MIMETypes.WEBM]: StreamTypes.prog,\n [MIMETypes.HLS]: StreamTypes.hls,\n [MIMETypes.DASH]: StreamTypes.dash,\n };\n\n return MIME_TYPE_TO_STREAM_TYPE_MAP[mimeType];\n}\n","import {Event} from './Event';\n\nexport enum VideoStartFailedReason {\n PAGE_CLOSED = 'PAGE_CLOSED',\n PLAYER_ERROR = 'PLAYER_ERROR',\n TIMEOUT = 'TIMEOUT',\n UNKNOWN = 'UNKNOWN',\n}\n\nexport function createVideoStartFailedReason(stateMachineEvent: string | undefined): VideoStartFailedReason {\n switch (stateMachineEvent) {\n case Event.ERROR:\n return VideoStartFailedReason.PLAYER_ERROR;\n case Event.UNLOAD:\n return VideoStartFailedReason.PAGE_CLOSED;\n case Event.MANUAL_SOURCE_CHANGE:\n return VideoStartFailedReason.PAGE_CLOSED;\n case Event.SOURCE_UNLOADED:\n return VideoStartFailedReason.PAGE_CLOSED;\n case Event.VIDEOSTART_TIMEOUT:\n return VideoStartFailedReason.TIMEOUT;\n\n default:\n return VideoStartFailedReason.UNKNOWN;\n }\n}\n","import {isNotNullish} from '../utils/Utils';\n\nimport {FeatureConfig} from './FeatureConfig';\n\nexport abstract class Feature<TConfigContainer, TConfig extends FeatureConfig> {\n private _config?: TConfig = undefined;\n private _isEnabled = true;\n\n get config(): TConfig | undefined {\n return this._config;\n }\n\n get isEnabled(): boolean {\n return this._isEnabled;\n }\n\n abstract reset(): void;\n abstract enabled(): void;\n abstract disabled(): void;\n abstract configured(authenticated: boolean, config?: TConfig): void;\n\n disable() {\n this._isEnabled = false;\n this.disabled();\n }\n\n configure(authenticated: boolean, configContainer?: TConfigContainer): TConfig | undefined {\n if (isNotNullish(configContainer)) {\n this._config = this.extractConfig(configContainer);\n }\n this.configured(authenticated, this._config);\n return this._config;\n }\n\n abstract extractConfig(configContainer: TConfigContainer): TConfig | undefined;\n}\n","import {logger} from '../utils/Logger';\n\nimport {Feature} from './Feature';\nimport {FeatureConfig} from './FeatureConfig';\n\nexport class FeatureManager<TConfigContainer> {\n private features: Array<Feature<TConfigContainer, FeatureConfig>> = [];\n\n registerFeatures(features: Array<Feature<TConfigContainer, FeatureConfig>>) {\n this.features = features;\n }\n\n unregisterFeatures() {\n this.features.forEach((feature) => feature.disable());\n this.features = [];\n }\n\n resetFeatures() {\n this.features.forEach((feature) => feature.reset());\n }\n\n configureFeatures(authenticated: boolean, featureConfigs?: TConfigContainer) {\n this.features = this.features.filter((feature) => {\n const config = feature.configure(authenticated, featureConfigs);\n if (!authenticated || config?.enabled !== true) {\n logger.log(`Disabling feature ${feature.constructor.name} as it isn't enabled according to license callback.`);\n feature.disable();\n return false;\n }\n return true;\n });\n this.features.forEach((feature) => feature.enabled());\n }\n}\n","import {CollectorConfig} from '../../types/AnalyticsConfig';\nimport {post} from '../../utils/Http';\nimport {ANALYTICS_BACKEND_BASE_URL} from '../../utils/Settings';\nimport {isNotNullish, joinUrls} from '../../utils/Utils';\nimport {HttpRequest} from '../httprequesttracking/HttpRequest';\n\nimport {ErrorData} from './ErrorData';\nimport {ErrorDetail} from './ErrorDetail';\n\nexport class ErrorDetailBackend {\n get queue(): ReadonlyArray<ErrorDetail> {\n return this._queue;\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(value: boolean) {\n this._enabled = value;\n }\n\n static copyErrorDetailTruncateStringsAndUrls(\n errorDetail: ErrorDetail,\n maxStringLength: number,\n maxUrlLength: number,\n ): ErrorDetail {\n return {\n ...errorDetail,\n message: errorDetail.message?.substr(0, maxStringLength),\n data: this.copyErrorDataTruncateStrings(errorDetail.data, maxStringLength),\n httpRequests: errorDetail.httpRequests?.map((request) => this.copyHttpRequestTruncateUrls(request, maxUrlLength)),\n };\n }\n\n static copyHttpRequestTruncateUrls(httpRequest: HttpRequest, maxLength: number): HttpRequest {\n return {\n ...httpRequest,\n url: httpRequest.url?.substr(0, maxLength),\n lastRedirectLocation: httpRequest.lastRedirectLocation?.substr(0, maxLength),\n };\n }\n\n static copyErrorDataTruncateStrings(errorData: ErrorData, maxStringLength: number): ErrorData {\n return {\n ...errorData,\n exceptionMessage: errorData.exceptionMessage?.substr(0, maxStringLength),\n additionalData: errorData.additionalData?.substr(0, maxStringLength),\n };\n }\n\n static copyErrorDetailTruncateHttpRequests(errorDetail: ErrorDetail, maxRequests: number): ErrorDetail {\n return {\n ...errorDetail,\n httpRequests: errorDetail.httpRequests?.slice(-maxRequests),\n };\n }\n\n // We use these as upper limits to avoid clients bombing us with data, actual truncation to documented limits is\n // happening in ingress\n private static MAX_URL_LENGTH = 450;\n private static MAX_STRING_LENGTH = 2000;\n\n private readonly backendUrl: string;\n private readonly _queue: ErrorDetail[] = [];\n private _enabled = false;\n\n constructor(collectorConfig: CollectorConfig | undefined) {\n this.backendUrl = joinUrls(collectorConfig?.backendUrl ?? ANALYTICS_BACKEND_BASE_URL, '/analytics/error');\n }\n\n limitHttpRequestsOfQueuedErrorDetails(max: number) {\n this._queue.forEach((value, index) => {\n this._queue[index] = ErrorDetailBackend.copyErrorDetailTruncateHttpRequests(value, max);\n });\n }\n\n send(errorDetail: ErrorDetail) {\n const errorDetailCopy = ErrorDetailBackend.copyErrorDetailTruncateStringsAndUrls(\n errorDetail,\n ErrorDetailBackend.MAX_STRING_LENGTH,\n ErrorDetailBackend.MAX_URL_LENGTH,\n );\n if (this.enabled) {\n post(this.backendUrl, errorDetailCopy, () => undefined);\n } else {\n this._queue.push(errorDetailCopy);\n }\n }\n\n flush() {\n const copy = [...this._queue];\n let element = copy.shift();\n while (isNotNullish(element)) {\n this.removeFromQueue(element);\n this.send(element);\n element = copy.shift();\n }\n }\n\n clear() {\n this._queue.splice(0, this._queue.length);\n }\n\n private removeFromQueue(element: ErrorDetail) {\n const index = this._queue.findIndex((value) => value === element);\n if (index >= 0) {\n this._queue.splice(index, 1);\n }\n }\n}\n","import {Subscribable} from '../../core/EventDispatcher';\nimport {CollectorConfig} from '../../types/AnalyticsConfig';\nimport {FeatureConfigContainer} from '../../types/FeatureConfigContainer';\nimport {logger} from '../../utils/Logger';\nimport {getCurrentTimestamp, isNullish, tryJSONStringify} from '../../utils/Utils';\nimport {VERSION} from '../../utils/Version';\nimport {Feature} from '../Feature';\nimport {HttpRequestTracking} from '../httprequesttracking/HttpRequestTracking';\n\nimport {ErrorDetail} from './ErrorDetail';\nimport {ErrorDetailBackend} from './ErrorDetailBackend';\nimport {ErrorDetailTrackingConfig} from './ErrorDetailTrackingConfig';\nimport {OnErrorDetailEventObject} from './OnErrorDetailEventObject';\n\nexport interface ErrorDetailTrackingSettingsProvider {\n readonly licenseKey: string;\n readonly domain: string;\n readonly impressionId: string;\n readonly collectorConfig?: CollectorConfig;\n}\n\nexport class ErrorDetailTracking extends Feature<FeatureConfigContainer, ErrorDetailTrackingConfig> {\n private errorIndex = 0;\n\n constructor(\n private settingsProvider: ErrorDetailTrackingSettingsProvider,\n private backend: ErrorDetailBackend,\n private subscribables: Array<Subscribable<OnErrorDetailEventObject>>,\n private httpRequestTracking: HttpRequestTracking | undefined,\n ) {\n super();\n subscribables.forEach((subscribable) => subscribable.subscribe(this.onErrorHandler));\n }\n\n reset(): void {\n this.httpRequestTracking?.reset();\n this.errorIndex = 0;\n }\n\n enabled(): void {\n this.backend.enabled = true;\n this.backend.flush();\n }\n\n disabled(): void {\n this.errorIndex = 0;\n this.httpRequestTracking?.disable();\n this.backend.clear();\n this.subscribables.forEach((subscribable) => subscribable.unsubscribe(this.onErrorHandler));\n }\n\n configured(_authenticated: boolean, config?: ErrorDetailTrackingConfig): void {\n const maxRequests = Math.max(config?.numberOfHttpRequests ?? 0, 0);\n this.httpRequestTracking?.configure(maxRequests);\n this.backend.limitHttpRequestsOfQueuedErrorDetails(maxRequests);\n }\n\n extractConfig(configContainer: FeatureConfigContainer): ErrorDetailTrackingConfig | undefined {\n return configContainer.errorDetails;\n }\n\n private onErrorHandler = (event: OnErrorDetailEventObject) => {\n try {\n if (!this.isEnabled) {\n return;\n }\n\n const httpRequests = this.httpRequestTracking?.httpRequests;\n const httpRequestsCopy = isNullish(httpRequests) ? undefined : [...httpRequests];\n const errorIndex = this.errorIndex;\n this.errorIndex++;\n\n const errorDetail: ErrorDetail = {\n platform: 'web',\n licenseKey: this.settingsProvider.licenseKey,\n domain: this.settingsProvider.domain,\n impressionId: this.settingsProvider.impressionId,\n analyticsVersion: VERSION,\n errorId: errorIndex,\n timestamp: getCurrentTimestamp(),\n code: event.code,\n message: event.message,\n data: event.errorData ?? {\n additionalData: undefined,\n exceptionMessage: undefined,\n exceptionStacktrace: undefined,\n },\n httpRequests: httpRequestsCopy,\n severity: event.severity,\n };\n\n logger.log(`ErrorDetailTracking.onError: ${tryJSONStringify(errorDetail)}`);\n this.backend.send(errorDetail);\n } catch (error) {\n logger.error(`ErrorDetailTracking.onError: Error in handler`, error);\n }\n };\n}\n","import {getCustomDataString, transferCustomDataFields} from '../utils/Utils';\n\nexport interface CustomDataValues {\n customData1?: string;\n customData2?: string;\n customData3?: string;\n customData4?: string;\n customData5?: string;\n customData6?: string;\n customData7?: string;\n customData8?: string;\n customData9?: string;\n customData10?: string;\n customData11?: string;\n customData12?: string;\n customData13?: string;\n customData14?: string;\n customData15?: string;\n customData16?: string;\n customData17?: string;\n customData18?: string;\n customData19?: string;\n customData20?: string;\n customData21?: string;\n customData22?: string;\n customData23?: string;\n customData24?: string;\n customData25?: string;\n customData26?: string;\n customData27?: string;\n customData28?: string;\n customData29?: string;\n customData30?: string;\n customData31?: string;\n customData32?: string;\n customData33?: string;\n customData34?: string;\n customData35?: string;\n customData36?: string;\n customData37?: string;\n customData38?: string;\n customData39?: string;\n customData40?: string;\n customData41?: string;\n customData42?: string;\n customData43?: string;\n customData44?: string;\n customData45?: string;\n customData46?: string;\n customData47?: string;\n customData48?: string;\n customData49?: string;\n customData50?: string;\n customData51?: string;\n customData52?: string;\n customData53?: string;\n customData54?: string;\n customData55?: string;\n customData56?: string;\n customData57?: string;\n customData58?: string;\n customData59?: string;\n customData60?: string;\n customData61?: string;\n customData62?: string;\n customData63?: string;\n customData64?: string;\n customData65?: string;\n customData66?: string;\n customData67?: string;\n customData68?: string;\n customData69?: string;\n customData70?: string;\n customData71?: string;\n customData72?: string;\n customData73?: string;\n customData74?: string;\n customData75?: string;\n customData76?: string;\n customData77?: string;\n customData78?: string;\n customData79?: string;\n customData80?: string;\n customData81?: string;\n customData82?: string;\n customData83?: string;\n customData84?: string;\n customData85?: string;\n customData86?: string;\n customData87?: string;\n customData88?: string;\n customData89?: string;\n customData90?: string;\n customData91?: string;\n customData92?: string;\n customData93?: string;\n customData94?: string;\n customData95?: string;\n customData96?: string;\n customData97?: string;\n customData98?: string;\n customData99?: string;\n customData100?: string;\n experimentName?: string;\n}\n\n/**\n * Lists all keys of the {@see CustomDataValues} interface.\n */\nexport const customDataValuesKeys: Array<keyof CustomDataValues> = [\n 'customData1',\n 'customData2',\n 'customData3',\n 'customData4',\n 'customData5',\n 'customData6',\n 'customData7',\n 'customData8',\n 'customData9',\n 'customData10',\n 'customData11',\n 'customData12',\n 'customData13',\n 'customData14',\n 'customData15',\n 'customData16',\n 'customData17',\n 'customData18',\n 'customData19',\n 'customData20',\n 'customData21',\n 'customData22',\n 'customData23',\n 'customData24',\n 'customData25',\n 'customData26',\n 'customData27',\n 'customData28',\n 'customData29',\n 'customData30',\n 'customData31',\n 'customData32',\n 'customData33',\n 'customData34',\n 'customData35',\n 'customData36',\n 'customData37',\n 'customData38',\n 'customData39',\n 'customData40',\n 'customData41',\n 'customData42',\n 'customData43',\n 'customData44',\n 'customData45',\n 'customData46',\n 'customData47',\n 'customData48',\n 'customData49',\n 'customData50',\n 'customData51',\n 'customData52',\n 'customData53',\n 'customData54',\n 'customData55',\n 'customData56',\n 'customData57',\n 'customData58',\n 'customData59',\n 'customData60',\n 'customData61',\n 'customData62',\n 'customData63',\n 'customData64',\n 'customData65',\n 'customData66',\n 'customData67',\n 'customData68',\n 'customData69',\n 'customData70',\n 'customData71',\n 'customData72',\n 'customData73',\n 'customData74',\n 'customData75',\n 'customData76',\n 'customData77',\n 'customData78',\n 'customData79',\n 'customData80',\n 'customData81',\n 'customData82',\n 'customData83',\n 'customData84',\n 'customData85',\n 'customData86',\n 'customData87',\n 'customData88',\n 'customData89',\n 'customData90',\n 'customData91',\n 'customData92',\n 'customData93',\n 'customData94',\n 'customData95',\n 'customData96',\n 'customData97',\n 'customData98',\n 'customData99',\n 'customData100',\n\n 'experimentName',\n];\n\n/**\n * The number of CustomDataXX fields in {@see CustomDataValues}.\n */\nexport const customDataFieldCount = customDataValuesKeys.filter((i) => i.match('customData\\\\d+')).length;\n\n/**\n * We are extracting the customData fields explicitly to make sure that there is not a different object passed\n */\nexport const extractCustomDataFieldsOnly = (input: CustomDataValues): CustomDataValues => {\n const retVal: CustomDataValues = {};\n customDataValuesKeys.forEach((key) => {\n if (input[key]) {\n retVal[key] = input[key];\n }\n });\n return retVal;\n};\n\nexport const sanitizeCustomDataValues = (customDataValues: CustomDataValues): CustomDataValues => {\n const extracted = extractCustomDataFieldsOnly(customDataValues);\n\n const sanitizedCustomDataValues: CustomDataValues = {};\n transferCustomDataFields(extracted, sanitizedCustomDataValues);\n // fix a bug of transferCustomDataFields that does not transfer 'experimentName' field, because it is not named 'customDataXX'\n // should be fixed with https://bitmovin.atlassian.net/browse/AN-5182\n sanitizedCustomDataValues.experimentName = getCustomDataString(extracted.experimentName);\n\n return sanitizedCustomDataValues;\n};\n","import {FeatureConfigContainer} from './FeatureConfigContainer';\n\nexport interface LicensingRequest {\n key?: string;\n domain: string;\n version: string;\n}\n\nexport enum LicensingResult {\n Denied = 'denied',\n Granted = 'granted',\n Skip = 'skip',\n}\n\nexport interface LicensingResponse {\n status: LicensingResult;\n message: string;\n features?: FeatureConfigContainer;\n}\n\nexport type LicenseCallFunc = (\n key: string,\n domain: string,\n version: string,\n baseUrl: string,\n) => Promise<LicensingResponse>;\n","import {PlayerSize} from '../enums/PlayerSize';\nimport {StreamTypes} from '../enums/StreamTypes';\nimport {isNullish} from '../utils/Utils';\n\nexport interface PlaybackInfo {\n audioBitrate?: number;\n audioCodec?: string;\n audioLanguage?: string;\n castTech?: string;\n droppedFrames: number;\n isCasting?: boolean;\n isLive?: boolean;\n isMuted?: boolean;\n m3u8Url?: string;\n mpdUrl?: string;\n playerTech?: string;\n progUrl?: string;\n screenHeight?: number;\n screenWidth?: number;\n size?: PlayerSize;\n streamFormat?: string;\n subtitleEnabled?: boolean;\n subtitleLanguage?: string;\n videoBitrate?: number;\n videoCodec?: string;\n videoDuration?: number;\n videoPlaybackHeight?: number;\n videoPlaybackWidth?: number;\n videoTitle?: string;\n videoWindowHeight?: number;\n videoWindowWidth?: number;\n}\n\nexport function normalizeVideoDuration(playerVideoDuration: number | null | undefined): number {\n // This covers Live streams and any case in which the duration is not known\n // which should report 0 as videoDuration\n if (isNullish(playerVideoDuration) || Number.isNaN(playerVideoDuration) || playerVideoDuration === Infinity) {\n return 0;\n }\n return playerVideoDuration;\n}\n\nexport function buildPlaybackInfoStreamTypeFields(\n streamType: StreamTypes | undefined,\n streamUrl: string | undefined,\n): Pick<PlaybackInfo, 'm3u8Url' | 'mpdUrl' | 'progUrl' | 'streamFormat'> {\n const DEFAULT_RESULT = {\n // set the stream type as it is (except null, that should be converted to undefined)\n streamFormat: streamType ?? undefined,\n // If the stream url is there, set it as \"progUrl\", even when the stream type is not recognized (unknown / nullish).\n // Why?\n // There was no clear reason why when this utility fn was created, it was just current written code/behavior\n // of our adapters, and for that reason it was copy&pasted here.\n progUrl: streamUrl,\n };\n\n if (isNullish(streamType)) {\n return DEFAULT_RESULT;\n }\n\n if (streamType === StreamTypes.dash) {\n return {streamFormat: streamType, mpdUrl: streamUrl};\n }\n if (streamType === StreamTypes.hls) {\n return {streamFormat: streamType, m3u8Url: streamUrl};\n }\n if (streamType === StreamTypes.prog) {\n return {streamFormat: streamType, progUrl: streamUrl};\n }\n\n return DEFAULT_RESULT;\n}\n","import type {VideoStartFailedReason} from '../enums/VideoStartFailedReason';\n\nimport type {AnalyticsConfig} from './AnalyticsConfig';\nimport type {AnalyticsEventBase, CustomDataValuesEvent, ErrorEvent, QualityChangeEvent} from './EventData';\nimport type {Sample} from './Sample';\nimport type {SourceMetadata} from './SourceMetadata';\n\nexport type HeartbeatPayload = {\n buffered?: Sample['buffered'];\n /**\n * Flag indicating that the event was triggered by a program change.\n *\n * `true` if the event was triggered by a program change, `undefined` otherwise to not set it as a property in the sample.\n */\n isProgramChange?: true;\n played?: Sample['played'];\n /** Flag indicating that the event was triggered by SSAI */\n triggeredBySsai?: boolean;\n};\n\nexport interface StateMachineCallbacks {\n setup: (duration: number, state: string) => void;\n startup: (duration: number, state: string) => void;\n /** Should reset the analytics, update the source metadata, and send a \"program change startup sample\" */\n programChange: (sourceMetadata: SourceMetadata) => void;\n /** Should only update the source metadata in the analytics module, but without sending any sample. */\n updateSourceMetadata: (sourceMetadata: SourceMetadata) => void;\n playing: (duration: number, state: string) => void;\n heartbeat: (duration: number, state: 'playing' | 'rebuffering', payload: HeartbeatPayload) => void;\n /**\n * Should send a sample with state \"qualitychange\" and duration 0\n */\n qualitychange: (event: QualityChangeEvent) => void;\n /**\n * Should update the qualityInfo on the current sample but not send any sample, e.g when a qualityChange occurs during\n * pause, seeking or buffering or when the QUALITY_CHANGE_THRESHOLD was hit\n */\n updateSampleQualityInfo: (event: QualityChangeEvent) => void;\n audiotrack_changing: () => void;\n pause: (duration: number, state: string) => void;\n /**\n * Should send a sample with `state: \"seeking\"` and `duration` set to the duration of the seeking.\n */\n seeking: (duration: number) => void;\n rebuffering: (duration: number, state: string) => void;\n error: (event: Readonly<ErrorEvent>) => void;\n /**\n * @deprecated should not be used at all.\n *\n * Instead, the \"end\" player event should transition state machine to PAUSE state\n *\n * https://bitmovin.atlassian.net/browse/AN-5134\n */\n end: (duration: number, state: string) => void;\n unload: (duration: number, state: string) => void;\n ad: (duration: number, state: string) => void;\n mute: () => void;\n unMute: () => void;\n subtitle_changing: () => void;\n setVideoTimeEndFromEvent: (analyticsEventBase: AnalyticsEventBase) => void;\n setVideoTimeStartFromEvent: (analyticsEventBase: AnalyticsEventBase) => void;\n videoStartFailed: (duration: number, reason: VideoStartFailedReason) => void;\n startCasting: (duration: number, event: any) => void;\n casting: (duration: number, event: any) => void;\n manualSourceChange: (event: {config: AnalyticsConfig}) => void;\n initialSourceChange: (event: {config: AnalyticsConfig}) => void;\n muting_ready: (duration: number, state: string, event: any) => void;\n /**\n * Should change {@link CustomDataValues} of analytics module.\n *\n * @remarks\n *\n * It is called via the default \"onleavestate\" state machine callback, and because of that:\n * - it has to match the state name \"CUSTOMDATACHANGE\"\n * - each parameter has to of `undefined` type (unintentionally, it can be called at any time, from any state)\n */\n customdatachange: (\n duration: number | undefined,\n state: string | undefined,\n eventData: CustomDataValuesEvent | undefined,\n ) => void;\n\n /** shuts down the collection and removes/clears all timeouts, intervals, event listeners */\n release: () => void;\n}\n\n/**\n * {@link StateMachineCallbacks} object with each callback set to be empty function (doing nothing).\n *\n * Why?:\n * We need to set it as default value in {@link InternalAdapter} for use case, when {@link InternalAdapter}\n * is already created and listen to player events, but {@link Analytics} was not instantiated/initialized yet (that\n * should set correct {@link StateMachineCallbacks} implementation)\n */\nexport const defaultStateMachineCallbacks: StateMachineCallbacks = {\n setup: () => {},\n startup: () => {},\n programChange: () => {},\n updateSourceMetadata: () => {},\n playing: () => {},\n heartbeat: () => {},\n qualitychange: () => {},\n updateSampleQualityInfo: () => {},\n audiotrack_changing: () => {},\n pause: () => {},\n seeking: () => {},\n rebuffering: () => {},\n error: () => {},\n end: () => {},\n unload: () => {},\n ad: () => {},\n mute: () => {},\n unMute: () => {},\n subtitle_changing: () => {},\n setVideoTimeEndFromEvent: () => {},\n setVideoTimeStartFromEvent: () => {},\n videoStartFailed: () => {},\n startCasting: () => {},\n casting: () => {},\n manualSourceChange: () => {},\n initialSourceChange: () => {},\n muting_ready: () => {},\n customdatachange: () => {},\n release: () => {},\n};\n","import {appendSsaiRoutingParam, isSsaiRelatedSample} from '../core/ssai/ssaiUtils';\nimport type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\n\nimport {globalScope} from './globalScope';\nimport {post} from './Http';\nimport {joinUrls, noOp} from './Utils';\n\nexport class AnalyticsCall {\n private readonly analyticsServerUrl: string;\n private readonly adAnalyticsServerUrl: string;\n\n constructor(baseUrl: string) {\n this.analyticsServerUrl = joinUrls(baseUrl, 'analytics');\n this.adAnalyticsServerUrl = joinUrls(baseUrl, 'analytics/a');\n }\n\n sendRequest(sample: Sample, callback: () => void) {\n let analyticsUrl = this.analyticsServerUrl;\n if (isSsaiRelatedSample(sample)) {\n analyticsUrl = appendSsaiRoutingParam(analyticsUrl);\n }\n\n post(analyticsUrl, sample, callback);\n }\n\n sendUnloadRequest(sample: Sample) {\n const sendBeaconFallback = (data: Sample) => this.sendRequestSynchronous(data, noOp);\n\n let analyticsUrl = this.analyticsServerUrl;\n if (isSsaiRelatedSample(sample)) {\n analyticsUrl = appendSsaiRoutingParam(analyticsUrl);\n }\n\n this.trySendBeacon(sendBeaconFallback, analyticsUrl, sample);\n }\n\n private trySendBeacon(\n fallbackFunction: (data: any) => void,\n url: string,\n data: unknown,\n requestHeaders: {[headerName: string]: string} = {},\n ) {\n if (typeof globalScope.navigator?.sendBeacon === 'undefined') {\n fallbackFunction(data);\n } else {\n /**\n * With a Blob we can send payload but also http headers\n * @see https://stackoverflow.com/questions/40523469/navigator-sendbeacon-to-pass-header-information\n */\n const blob = new Blob([JSON.stringify(data)], requestHeaders);\n const success = globalScope.navigator.sendBeacon(url, blob);\n if (!success) {\n fallbackFunction(data);\n }\n }\n }\n\n sendRequestSynchronous(sample: Sample, callback: () => void) {\n let analyticsUrl = this.analyticsServerUrl;\n if (isSsaiRelatedSample(sample)) {\n analyticsUrl = appendSsaiRoutingParam(analyticsUrl);\n }\n\n post(analyticsUrl, sample, callback, false);\n }\n\n sendAdRequest(adSample: AdSample) {\n let adAnalyticsUrl = this.adAnalyticsServerUrl;\n if (isSsaiRelatedSample(adSample)) {\n adAnalyticsUrl = appendSsaiRoutingParam(adAnalyticsUrl);\n }\n\n const sendBeaconFallback = (data: AdSample) => post(adAnalyticsUrl, data, noOp);\n this.trySendBeacon(sendBeaconFallback, adAnalyticsUrl, adSample);\n }\n}\n","import {globalScope} from './globalScope';\nimport {isFunction, isNullish} from './Utils';\n\nconst videoFormatCodecMap: {[format: string]: string[]} = {\n avc: ['video/mp4; codecs=\"avc1.42000a\"'],\n vp9: ['video/mp4; codecs=\"vp09.00.50.08\"'],\n av1: ['video/mp4; codecs=\"av01.0.08M.08\"'],\n hevc: ['video/mp4; codecs=\"hev1.1.6.L93.B0\"'],\n};\n\nexport class CodecHelper {\n static get supportedVideoFormats(): string[] | undefined {\n if (isNullish(globalScope.MediaSource?.isTypeSupported) || !isFunction(globalScope.MediaSource.isTypeSupported)) {\n return undefined;\n }\n return Object.getOwnPropertyNames(videoFormatCodecMap).filter((format) =>\n videoFormatCodecMap[format].some((codec) => globalScope.MediaSource.isTypeSupported(codec)),\n );\n }\n}\n","export class EventDebugging {\n event: string | undefined;\n from: string | undefined;\n to: string | undefined;\n timestamp: number;\n eventObject: any;\n\n constructor(\n event: string | undefined,\n from: string | undefined,\n to: string | undefined,\n timestamp: number,\n eventObject: any,\n ) {\n this.event = event;\n this.from = from;\n this.to = to;\n this.timestamp = timestamp;\n this.eventObject = eventObject;\n }\n}\n","import {globalScope} from './globalScope';\nimport {logger} from './Logger';\nimport {isReactNative} from './Utils';\n\nexport function post(url: string, body: any, callback: any, async = true): void {\n // React Native doesn't support synchronous XMLHttpRequest\n // Force async mode in React Native environments\n if (isReactNative() && !async) {\n async = true;\n }\n\n let xhttp: any;\n let isLegacyXDomainRequestUsed = false;\n\n if (globalScope.XDomainRequest) {\n // XDomainRequest is the only way of having an XHR that supports CORS in IE8 and 9. At the time of IE8,\n // Microsoft decided to come up with their own CORS XHR instead of the standard CORS XMLHttpRequest\n // which is now used in IE10.\n // Since IE10, XDomainRequest has been deprecated and since IE11 removed.\n xhttp = new globalScope.XDomainRequest();\n isLegacyXDomainRequestUsed = true;\n } else {\n xhttp = new XMLHttpRequest();\n }\n\n const responseCallback = () => {\n if (xhttp.readyState == XMLHttpRequest.DONE) {\n if (xhttp.responseText <= 0) {\n return;\n }\n\n const sampleResponse = JSON.parse(xhttp.responseText);\n\n callback(sampleResponse);\n }\n };\n\n if (isLegacyXDomainRequestUsed) {\n xhttp.onload = responseCallback;\n } else {\n xhttp.onreadystatechange = responseCallback;\n }\n\n try {\n xhttp.open('POST', url, async);\n\n // XDomainRequest restriction: No custom headers may be added to the request\n // https://learn.microsoft.com/en-us/archive/blogs/ieinternals/xdomainrequest-restrictions-limitations-and-workarounds\n if (!isLegacyXDomainRequestUsed) {\n xhttp.setRequestHeader('Content-Type', 'text/plain');\n }\n\n xhttp.send(JSON.stringify(body));\n } catch (e) {\n logger.error('Failed to send POST request.', e);\n }\n}\n","import {LicensingResponse} from '../types/LicensingRequest';\n\nimport {post} from './Http';\nimport {joinUrls} from './Utils';\n\nexport function LicenseCall(key: string, domain: string, version: string, baseUrl: string): Promise<LicensingResponse> {\n const licenseServerUrl = joinUrls(baseUrl, '/licensing');\n const licensingRequest = {\n analyticsVersion: version,\n domain,\n key,\n };\n return new Promise<LicensingResponse>((resolve) => {\n post(licenseServerUrl, licensingRequest, (response) => {\n resolve(response);\n });\n });\n}\n","import {AnalyticsConfig} from '../types/AnalyticsConfig';\n\n/**\n * Uses a Singleton design pattern.\n *\n * We want to ensure that only one object of its kind exists and provides a single point of access to it,\n * to be able to control enabled/disabled `console` logs for customer in whole code base.\n */\nclass Logger {\n private static instance: Logger;\n\n static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n\n return Logger.instance;\n }\n\n private analyticsDebugConfig: Readonly<AnalyticsConfig['debug']>;\n\n private constructor() {}\n\n initialize(analyticsDebugConfig: AnalyticsConfig['debug']) {\n this.analyticsDebugConfig = analyticsDebugConfig;\n }\n\n //#region Console API\n log(message?: unknown, ...optionalParams: unknown[]) {\n if (!this.enabled) {\n return;\n }\n console.log(message, optionalParams); //eslint-disable-line no-console\n }\n\n table(tabularData: unknown, properties?: readonly string[]) {\n if (!this.enabled) {\n return;\n }\n console.table(tabularData, properties); //eslint-disable-line no-console\n }\n\n warn(message?: unknown, ...optionalParams: unknown[]) {\n if (!this.enabled) {\n return;\n }\n console.warn(message, optionalParams); //eslint-disable-line no-console\n }\n\n error(message?: unknown, ...optionalParams: unknown[]) {\n if (!this.enabled) {\n return;\n }\n console.error(message, optionalParams); //eslint-disable-line no-console\n }\n\n /**\n * Outputs an error message to user/customer console.\n *\n * Does not relay on {@link Logger#enabled}! because it should deliver the error information to user/customer.\n */\n errorMessageToUser(message?: unknown, ...optionalParams: unknown[]) {\n console.error(message, ...optionalParams); //eslint-disable-line no-console\n }\n //#endregion\n\n /** `true` if {@link AnalyticsConfig#debug} was set */\n private get enabled() {\n return (this.analyticsDebugConfig as boolean) || false;\n }\n}\n\nexport const padRight = (str: string | undefined, length: number) => {\n const padStr = new Array(length).join(' ');\n return (str + padStr).slice(0, length);\n};\n\nexport const logger = Logger.getInstance();\n","export const MESSAGE_NAMESPACE = 'urn:x-cast:com.bitmovin.analytics.cast';\nexport const ANALYTICS_BACKEND_BASE_URL = 'https://analytics-ingress-global.bitmovin.com';\n\nexport const ANALYTICS_LICENSECALL_TIMEOUT = 1000 * 60;\nexport const ANALYTICS_VIDEOSTART_TIMEOUT = 1000 * 60; // in milliseconds\n\nexport const ANALYTICS_QUALITY_CHANGE_COUNT_THRESHOLD = 50;\nexport const ANALYTICS_QUALITY_CHANGE_COUNT_RESET_INTERVAL = 60 * 60 * 1000;\n\n/**\n * Time (in milliseconds) of consecutive buffering until a REBUFFER_TIMEOUT_ERROR is raised.\n */\nexport const ANALYTICS_REBUFFER_TIMEOUT = 1000 * 60 * 2;\n\n/**\n * minimal time (in seconds) a seek event should have in order to be recogniced as seek\n */\nexport const ANALYTICS_MIN_SEEK_DIFFERENCE_THRESHOLD = 3;\n\n/**\n * Has to be greater or equal than Ingress side limit (currently 1000).\n */\nexport const SEQUENCE_NUMBER_LIMIT = 1000;\n","import {PAGE_LOAD_TYPE} from '../enums/PageLoadType';\nimport {ErrorSeverity} from '../types/AnalyticsConfig';\nimport type {CustomDataValues} from '../types/CustomDataValues';\nimport * as CustomDataUtils from '../types/CustomDataValues';\n\nimport {isDocumentHidden} from './documentUtils';\nimport {getGlobalNavigatorProduct} from './globalScopeUtils';\nimport {endsWith, startsWith} from './stringUtils';\n\n/**\n * Performs a loose equality check (==), which means it checks for both null and undefined.\n *\n * @returns {value is null | undefined} `true` if the given value is `null` or `undefined`.\n */\nexport const isNullish = (value: unknown): value is null | undefined => value == null;\n\n/**\n *\n * @returns {value is Exclude<unknown, null | undefined>} `true` if the given value is not `null` and is not `undefined`.\n */\nexport const isNotNullish = <T = unknown>(value: T): value is Exclude<T, null | undefined> => !isNullish(value);\n\n/**\n * @returns {value is boolean} `true` if the given value is {@link isNotNullish} and is type of `boolean`.\n */\nexport const isBoolean = (value: unknown): value is boolean => !isNullish(value) && typeof value === 'boolean';\n\nexport const toBoolean = (value: unknown): boolean => Boolean(value).valueOf();\n\n/**\n * Checks if a value is a non-null object.\n *\n * We must exclude `null` explicitly, because `typeof null === \"object\"`\n *\n * @returns {value is Record<string, unknown>} `true` if the value is a non-null object, otherwise `false`.\n */\nexport const isObject = <T extends object>(value: T): value is T => {\n return isNotNullish(value) && typeof value === 'object';\n};\n\n/**\n * Checks if a value is a plain object (not an array, function, or built-in instance).\n *\n * @returns {value is Record<string, unknown>} `true` if the value is a plain object, otherwise `false`.\n */\nexport const isPlainObject = <T extends object>(value: T): value is T => {\n return Object.prototype.toString.call(value) === '[object Object]';\n};\n\n/**\n * Checks if a value is a function.\n *\n * @returns {value is function} `true` if the value is a function, otherwise `false`.\n */\nexport const isFunction = <T extends (...args: unknown[]) => unknown>(value: unknown): value is T =>\n typeof value === 'function';\n\n/**\n * Checks if a value is of type ErrorSeverity.\n *\n * @returns {value is ErrorSeverity} `true` if the value is of type ErrorSeverity, otherwise `false`.\n */\nexport function isErrorSeverity(anything: unknown): anything is ErrorSeverity {\n // invalid, when not defined as one of string values we expect\n return anything === 'CRITICAL' || anything === 'INFO';\n}\n\n/** Remove trailing slash from a path, if it exists. */\nexport const removeTrailingSlash = (path: string): string => {\n return path.replace(/\\/$/g, '');\n};\n\n/** Take a time in seconds and return a value that represents a time in milliseconds, rounded to the nearest integer */\nexport const calculateTime = (timeInSeconds: number) => Math.round(timeInSeconds * 1000);\n\n/** Same as {@link calculateTime} but if time is \"nullish\", then the return value is `undefined` */\nexport const calculateTimeWithUndefined = (timeInSeconds: number | null | undefined): number | undefined => {\n if (isNullish(timeInSeconds)) {\n return undefined;\n }\n return calculateTime(timeInSeconds);\n};\n\n/**\n * @deprecated Use directly `Date.now()` instead\n *\n * Return the current time in milliseconds.\n */\nexport const getCurrentTimestamp = (): number => {\n return Date.now();\n};\n\n/**\n * Empty function returns undefined\n *\n * @deprecated\n */\nexport const noOp = () => undefined;\n\nexport const getCustomDataString = (customData: any): string | undefined => {\n if (typeof customData === 'object') {\n return tryJSONStringify(customData);\n } else if (isFunction(customData)) {\n return getCustomDataString(customData());\n } else if (typeof customData === 'undefined') {\n return customData;\n } else if (typeof customData !== 'string') {\n return String(customData);\n }\n\n return customData;\n};\n\nexport const transferCustomDataFields = (fromConfig: CustomDataValues, toConfig: CustomDataValues) => {\n for (let i = 1; i <= CustomDataUtils.customDataFieldCount; i++) {\n const customDataField = `customData${i}`;\n toConfig[customDataField] = getCustomDataString(fromConfig[customDataField]);\n }\n};\n\n/**\n * Determine if the page was loaded in the foreground or background\n */\nexport function getPageLoadType(): PAGE_LOAD_TYPE {\n if (isDocumentHidden()) {\n return PAGE_LOAD_TYPE.BACKGROUND;\n }\n return PAGE_LOAD_TYPE.FOREGROUND;\n}\n\nexport const calculatePercentage = (numerator?: number, denominator?: number): number | undefined => {\n if (denominator === undefined || denominator === 0) {\n return undefined;\n }\n return Math.round(((numerator || 0) / denominator) * 100);\n};\n\nexport const getURLResourceName = (url: string): string => {\n if (url.length === 0) {\n return '';\n }\n return url.split('/').pop() || '';\n};\n\nexport const joinUrls = (...args: string[]): string => {\n return args.reduce((prev, current) => {\n const prevUrlValue = endsWith(prev, '/') && current !== undefined ? prev.substr(0, prev.length - 1) : prev;\n const nextUrlValue = startsWith(current, '/') ? current.substr(1) : current;\n return prevUrlValue + '/' + nextUrlValue;\n });\n};\n\n/**\n * Detect if running in a React Native environment using navigator.product\n * https://github.com/facebook/react-native/commit/3c65e62183ce05893be0822da217cb803b121c61\n * https://github.com/facebook/react-native/issues/1331\n * https://stackoverflow.com/questions/39468022/how-do-i-know-if-my-code-is-running-as-react-native\n * navigator object from vega os simulator {\"product\":\"ReactNative\",\"userAgent\":\"ReactNative\"}\n */\nexport const isReactNative = (): boolean => {\n return getGlobalNavigatorProduct() === 'ReactNative';\n};\n\n/**\n * Determine if the audio is muted based on the player muted state and current volume.\n *\n * @param playerIsMuted `true` means muted and `false` means not muted.\n * @param playerVolume A double values must fall between 0 and 1, where 0 is effectively muted and 1 is the loudest possible value.\n */\nexport const isAudioMuted = (playerIsMuted: boolean, playerVolume: number) => {\n /** Audio volume below this delta is considered zero. */\n const VOLUME_DELTA = 0.01;\n\n return playerIsMuted || playerVolume < VOLUME_DELTA;\n};\n\nexport const tryJSONStringify = (obj: unknown): string | undefined => {\n if (isNullish(obj)) {\n return undefined;\n }\n\n try {\n return JSON.stringify(obj);\n } catch {\n return undefined;\n }\n};\n\n/**\n * Checks if a value is an `ArrayBuffer` instance.\n *\n * Uses `Object.prototype.toString` for reliable detection across different\n * execution contexts (e.g. iframes, workers) where `instanceof ArrayBuffer` may fail.\n *\n * @returns {value is ArrayBuffer} `true` if the value is an `ArrayBuffer`, otherwise `false`.\n */\nexport function isArrayBuffer(value: unknown): value is ArrayBuffer {\n return Object.prototype.toString.call(value) === '[object ArrayBuffer]';\n}\n","declare global {\n /** Variable is defined by webpack.DefinePlugin during the build process. */\n const __VERSION__: string;\n}\n\nexport const VERSION: string = __VERSION__;\n","import {addDocumentEventListener, getDocumentPropertyWithPrefix, removeDocumentEventListener} from './documentUtils';\nimport {globalScope} from './globalScope';\nimport {logger} from './Logger';\nimport {isValidString} from './stringUtils';\nimport {isNullish} from './Utils';\n\nexport class ViewportTracker {\n private onIntersectionChanged: () => void;\n private observer?: IntersectionObserver;\n private element: HTMLElement;\n private inViewport?: boolean = undefined;\n private threshold: number;\n private hiddenPropertyName: string | undefined;\n private visibilityChange?: string;\n\n constructor(element: HTMLElement, onIntersectionChanged: () => void, threshold = 1.0) {\n this.threshold = threshold;\n this.onIntersectionChanged = onIntersectionChanged;\n this.element = element;\n\n try {\n const options: IntersectionObserverInit = {\n root: null,\n rootMargin: '0px',\n threshold,\n };\n this.observer = new IntersectionObserver((entries, observer) => this.handleIntersect(entries, observer), options);\n this.observer.observe(element);\n } catch (_error) {\n logger.log(\"Couldn't create instance of IntersectionObserver. timeInViewport will always be reported as 100%.\");\n }\n\n this.hiddenPropertyName = getDocumentPropertyWithPrefix('hidden');\n if (this.hiddenPropertyName) {\n this.visibilityChange = this.hiddenPropertyName.replace('hidden', '') + 'visibilitychange';\n addDocumentEventListener(\n this.visibilityChange,\n (this.handleVisibilityChange = this.handleVisibilityChange.bind(this)),\n false,\n );\n }\n }\n\n isHidden() {\n if (isNullish(globalScope.document) || !isValidString(this.hiddenPropertyName)) {\n return false;\n }\n\n return globalScope.document[this.hiddenPropertyName] === true;\n }\n\n isInViewport(): boolean {\n return !this.isHidden() && (isNullish(this.inViewport) ? true : this.inViewport);\n }\n\n dispose() {\n if (this.observer) {\n this.observer.unobserve(this.element);\n this.observer.disconnect();\n }\n if (this.visibilityChange) {\n removeDocumentEventListener(this.visibilityChange, this.handleVisibilityChange, false);\n }\n }\n\n private handleVisibilityChange() {\n this.onIntersectionChanged();\n }\n\n private handleIntersect(entries: IntersectionObserverEntry[], _observer: IntersectionObserver) {\n entries.forEach((i) => {\n if (i.target === this.element) {\n this.inViewport = !(i.intersectionRatio < this.threshold);\n }\n });\n this.onIntersectionChanged();\n }\n}\n","import {getGlobalWebOSApi} from './globalScopeUtils';\nimport {isBlank, isValidString} from './stringUtils';\n\n// Declaration merging to extend the Window interface with WebOS API\n// see: https://webostv.developer.lge.com/develop/references/webostvjs-webos\ndeclare global {\n interface Window {\n /**\n * @deprecated In webOS TV 4.x or lower, only PalmSystem is supported, and in webOS TV 5.0 or higher,\n * both PalmSystem and webOSSystem are supported. Although PalmSystem is still supported for backward compatibility,\n * future support is not guaranteed so it is strongly recommended that you use webOSSystem in webOS TV 5.0 or higher.\n *\n * @see https://webostv.developer.lge.com/develop/guides/app-lifecycle-management\n */\n PalmSystem?: {\n deviceInfo?: string;\n };\n\n /**\n * Represents the current system interface that should be used on webOS TV 5.0 or higher.\n *\n * @see https://webostv.developer.lge.com/develop/references/webostvjs-webos\n */\n webOSSystem?: {\n /**\n * @see https://webostv.developer.lge.com/develop/references/webostvjs-webos#deviceinfo\n */\n deviceInfo?: string;\n };\n }\n}\n\ntype WebOSDeviceInfo = {modelName: string};\n\nexport function getWebOSTVModelName(): string | undefined {\n try {\n const {webOSSystem, PalmSystem} = getGlobalWebOSApi();\n const info: WebOSDeviceInfo | undefined = webOSSystem?.deviceInfo\n ? JSON.parse(webOSSystem.deviceInfo)\n : PalmSystem?.deviceInfo && JSON.parse(PalmSystem.deviceInfo);\n if (isValidString(info?.modelName) && !isBlank(info?.modelName)) {\n return info.modelName;\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n","import {addGlobalEventListener, removeGlobalEventListener} from './globalScopeUtils';\n\ninterface EventListener {\n eventName: string;\n func: EventListenerOrEventListenerObject;\n}\n\nexport class WindowEventTracker {\n private trackedObjects: EventListener[] = [];\n\n addEventListener(eventName: string, func: EventListenerOrEventListenerObject) {\n this.trackedObjects.push({eventName, func});\n addGlobalEventListener(eventName, func);\n }\n\n release() {\n while (this.trackedObjects.length !== 0) {\n const obj = this.trackedObjects.pop();\n if (obj === undefined) {\n continue;\n }\n\n removeGlobalEventListener(obj.eventName, obj.func);\n }\n }\n}\n","import type {AnalyticsConfig, CollectorConfig} from '../types/AnalyticsConfig';\nimport {extractCustomDataFieldsOnly} from '../types/CustomDataValues';\nimport type {Sample} from '../types/Sample';\nimport type {SourceMetadata} from '../types/SourceMetadata';\n\nimport {getGlobalLocationHostname} from './globalScopeUtils';\nimport {logger} from './Logger';\nimport {isBlank, isValidString} from './stringUtils';\nimport * as Utils from './Utils';\nimport {isFunction, isNotNullish, isNullish} from './Utils';\n\n/**\n * Sanitize {@link AnalyticsConfig} to not be null/undefined\n *\n * Why we return the same config (same reference) passed to function as an argument?\n * Because in the past, we made a mistake and forget to prevent changing `AnalyticsConfig` vie kept reference\n * from outside. Now our customers are using this bug/feature, and we need to keep it for backward compatibility.\n * This should be fixed and changed in the future major release as part of `Collector API v3` changes.\n *\n * @returns A new empty config `{}`, if it was `null/undefined`, otherwise the same config (same reference).\n *\n */\nexport function sanitizeAnalyticsConfig(config: AnalyticsConfig | null | undefined): AnalyticsConfig {\n if (isNullish(config)) {\n return {};\n }\n\n if (!Utils.isBoolean(config.isLive)) {\n config.isLive = undefined;\n }\n\n if (isNotNullish(config.config) && isNotNullish(config.config.errorTransformerCallback)) {\n if (!isFunction(config.config!.errorTransformerCallback!.transform)) {\n config.config.errorTransformerCallback = undefined;\n }\n }\n\n return config;\n}\n\n/**\n * Log error with {@link logger}, if the new configuration is missing `title` property, but old configuration had one.\n */\nexport function guardConfigChangeAgainstMissingTitle(oldConfig: AnalyticsConfig, newConfig: AnalyticsConfig) {\n if (isNullish(oldConfig) || isNullish(newConfig)) {\n // handle undefined values even when argument type does not specify them\n // (defensive approach, because of old code from past and step by step refactorings)\n return;\n }\n\n if (oldConfig.title && isBlank(newConfig.title)) {\n logger.error('The new analytics configuration does not contain the field `title`');\n }\n}\n\n/**\n * Log error with {@link logger}, if the new configuration is missing `isLive` property, but old configuration had one.\n */\nexport function guardConfigChangeAgainstMissingIsLive(oldConfig: AnalyticsConfig, newConfig: AnalyticsConfig) {\n if (isNullish(oldConfig) || isNullish(newConfig)) {\n // handle undefined values even when argument type does not specify them\n // (defensive approach, because of old code from past and step by step refactorings)\n return;\n }\n\n if (oldConfig.isLive && isNullish(newConfig.isLive)) {\n logger.error(\n 'The new analytics configuration does not contain the field `isLive`. It will default to `false` which might be unintended? Once stream playback information is available the type will be populated.',\n );\n }\n}\n\n/**\n * Log warning with {@link logger}, if both `customUserId` and `userId` are set in the configuration.\n */\nexport function guardAgainstDuplicatedUserId(config: AnalyticsConfig) {\n if (isNullish(config)) {\n // handle undefined values even when argument type does not specify them\n // (defensive approach, because of old code from past and step by step refactorings)\n return;\n }\n\n if (isNotNullish(config.customUserId) && isNotNullish(config.userId)) {\n logger.warn(\n 'Configuration Warning: \\n' +\n 'CustomUserId and UserId are set in the config \\n' +\n 'Value of UserId will be used in sample \\n' +\n 'Please only use one configuration field to set your userId',\n );\n }\n}\n\nexport function getDeviceInformationFromAnalyticsConfig(\n config: AnalyticsConfig,\n): Sample['deviceInformation'] | undefined {\n if (isNullish(config)) {\n // handle undefined values even when argument type does not specify them\n // (defensive approach, because of old code from past and step by step refactorings)\n return undefined;\n }\n\n const deviceInformation: Sample['deviceInformation'] = {};\n\n if (isValidString(config.deviceType) && !isBlank(config.deviceType)) {\n // we are using `deviceInformation.model` field to pass `config.deviceType`, because of ingress\n // and how deviceInformation processing is implemented there.\n deviceInformation.model = config.deviceType;\n }\n\n if (isValidString(config.deviceClass) && !isBlank(config.deviceClass)) {\n deviceInformation.deviceClass = config.deviceClass;\n }\n\n if (Object.keys(deviceInformation).length === 0) {\n return undefined;\n }\n\n return deviceInformation;\n}\n\n/**\n * Get {@link CollectorConfig} `origin` field (if any), otherwise return sanitized hostname.\n */\nexport function getDomainFromAnalyticsConfig(config: AnalyticsConfig): string {\n const hostname = getGlobalLocationHostname();\n const fallbackDomain = hostname ? Utils.removeTrailingSlash(hostname) : '';\n return config?.config?.origin ?? fallbackDomain;\n}\n\nfunction removeSourceRelatedFields(config: AnalyticsConfig): AnalyticsConfig {\n const sourceSpecificProperties = ['cdnProvider', 'videoId', 'title', 'isLive', 'experimentName'];\n const customDataFieldsRegex = /customData\\d{1,3}$/g;\n\n for (const key in config) {\n if (isNotNullish(key.match(customDataFieldsRegex)) || sourceSpecificProperties.includes(key)) {\n delete config[key];\n }\n }\n\n return config;\n}\n\nfunction mergeCollectorConfig(\n oldCollectorConfig: CollectorConfig | undefined,\n newCollectorConfig: CollectorConfig | undefined,\n): CollectorConfig {\n if (isNotNullish(newCollectorConfig)) {\n // merging new config should enable the collector by default (unless explicitly disabled in the new config)\n return {...oldCollectorConfig, enabled: true, ...newCollectorConfig};\n }\n return oldCollectorConfig ?? {};\n}\n\nexport function mergeAnalyticsConfig(oldConfig: AnalyticsConfig, newConfig: AnalyticsConfig): AnalyticsConfig {\n const oldConfigWithoutSourceRelatedFields = removeSourceRelatedFields(oldConfig);\n const mergedCollectorConfig = mergeCollectorConfig(oldConfig.config, newConfig.config);\n\n return {\n ...oldConfigWithoutSourceRelatedFields,\n ...newConfig,\n config: mergedCollectorConfig,\n };\n}\n\nexport function applySourceMetadataToAnalyticsConfig(\n config: AnalyticsConfig,\n sourceMetadata: SourceMetadata,\n): AnalyticsConfig {\n let newConfig: AnalyticsConfig = {...config}; // create a new config object to avoid mutating the original one\n\n if (isNotNullish(sourceMetadata.title)) {\n newConfig.title = sourceMetadata.title;\n }\n\n if (isNotNullish(sourceMetadata.videoId)) {\n newConfig.videoId = sourceMetadata.videoId;\n }\n\n if (isNotNullish(sourceMetadata.cdnProvider)) {\n newConfig.cdnProvider = sourceMetadata.cdnProvider;\n }\n\n if (isNotNullish(sourceMetadata.isLive)) {\n newConfig.isLive = sourceMetadata.isLive;\n }\n\n if (isNotNullish(sourceMetadata.customData)) {\n // same style how to set custom data fields like we do in Analytics module\n newConfig = {\n ...newConfig,\n ...extractCustomDataFieldsOnly(sourceMetadata.customData),\n };\n }\n\n return newConfig;\n}\n","import type {AnalyticsConfig} from '../types/AnalyticsConfig';\n\nimport {getDomainFromAnalyticsConfig} from './analyticsConfigUtils';\nimport {logger} from './Logger';\nimport {isBlank} from './stringUtils';\n\n/**\n * Checks if the environment and config is set up correctly to allow proper collector initialization\n * @param config The analytics config to check\n * @returns true if setup is correct and full initialization possible\n */\nexport function areCollectorRequirementsValid(config: AnalyticsConfig): boolean {\n const errorMessages: string[] = [];\n\n // domain available - needed for license calls (authorization)\n const isDomainMissing = isBlank(getDomainFromAnalyticsConfig(config));\n if (isDomainMissing) {\n errorMessages.push(\n 'no `domain` value found (neither from `window.location` object nor provided by `AnalyticsConfig.config.origin`). Without this value, we cannot verify the origin of your analytics data. Please provide the registered domain via the config during collector creation.',\n );\n }\n\n if (errorMessages.length > 0) {\n const fullErrorMessage = 'Collector setup failed:' + errorMessages.join(' -- ');\n logger.errorMessageToUser(fullErrorMessage);\n }\n\n return !isDomainMissing;\n}\n","/**\n * documentUtils provides standalone functions for accessing browser document APIs.\n * This improves testability by allowing easy mocking of document-dependent functionality.\n */\n\nimport {logger} from './Logger';\nimport {isValidString} from './stringUtils';\nimport {isFunction, isNullish} from './Utils';\n\n/**\n * Get a property from document with vendor prefix support\n * Tries the standard property name first, then with webkit/moz/ms/o prefixes\n */\nexport const getDocumentPropertyWithPrefix = (prop: string): string | undefined => {\n if (isNullish(document)) {\n return undefined;\n }\n\n if (prop in document) {\n return prop;\n }\n\n const prefixes = ['webkit', 'moz', 'ms', 'o'];\n const pascalCase = prop.charAt(0).toUpperCase() + prop.slice(1);\n for (const prefix of prefixes) {\n const prefixedProp = prefix + pascalCase;\n if (prefixedProp in document) {\n return prefixedProp;\n }\n }\n\n return undefined;\n};\n\n/**\n * Check if the document is currently hidden (page visibility API)\n */\nexport const isDocumentHidden = (): boolean => {\n const hiddenProp = getDocumentPropertyWithPrefix('hidden');\n if (!isValidString(hiddenProp)) {\n return false;\n }\n\n return document[hiddenProp] === true;\n};\n\n/**\n * Check if a video element is currently in fullscreen mode\n */\nexport const isVideoInFullscreen = (): boolean => {\n const fullscreenProp = getDocumentPropertyWithPrefix('fullscreenElement');\n if (!isValidString(fullscreenProp)) {\n return false;\n }\n\n return document[fullscreenProp]?.nodeName === 'VIDEO';\n};\n\n/**\n * Add event listener to document\n *\n * Use this for document-level events that relate to the DOM structure and document state.\n * Some events ONLY fire on document (not on window):\n * - visibilitychange (& vendor-prefixed variants): tab/page visibility state\n * - fullscreenchange/fullscreenerror: fullscreen mode changes\n * - DOMContentLoaded: DOM parsed and ready (fires before window 'load')\n * - readystatechange: document.readyState changes\n *\n * Important: This function cannot be replaced with window.addEventListener because\n * the above events are document-specific and will not fire on window.\n *\n * We use vendor-prefixed events (webkitvisibilitychange, mozvisibilitychange, etc.)\n * for cross-browser compatibility, especially on older browsers and Smart TVs.\n */\nexport const addDocumentEventListener = (\n event: string,\n handler: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n): void => {\n if (isNullish(document) || !isFunction(document.addEventListener) || isNullish(handler)) {\n return;\n }\n\n // any-wrap needed to not confirm to type checks\n // we use vendor-prefixed events that are not part of the interface\n (document.addEventListener as any)(event, handler, options);\n};\n\n/**\n * Remove event listener from document\n *\n * @see addDocumentEventListener for details on when to use document vs window event listeners\n */\nexport const removeDocumentEventListener = (\n event: string,\n handler: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n): void => {\n if (isNullish(document) || !isFunction(document.removeEventListener) || isNullish(handler)) {\n return;\n }\n\n // any-wrap needed to not confirm to type checks\n // we use vendor-prefixed events that are not part of the interface\n (document.removeEventListener as any)(event, handler, options);\n};\n\n/**\n * Get a cookie value by name\n * @see https://www.w3schools.com/js/js_cookies.asp\n */\nexport const getCookie = (name: string): string | undefined => {\n if (isNullish(document)) {\n return undefined;\n }\n\n let allCookies: string[];\n try {\n allCookies = document.cookie.split(';');\n } catch (_error) {\n logger.log('failed to access cookie objects on document', _error);\n return undefined;\n }\n\n const cookieName = name + '=';\n for (const c of allCookies) {\n let cookie = c;\n while (cookie.charAt(0) === ' ') {\n cookie = cookie.substring(1); // trim spaces (if any) between ';' and next attribute\n }\n if (cookie.indexOf(cookieName) === 0) {\n return cookie.substring(cookieName.length, cookie.length);\n }\n }\n return '';\n};\n\n/**\n * Set a cookie with optional attributes\n */\nexport const setCookie = (\n name: string,\n value: string,\n attributes?: {domain?: string; expires?: string; maxAge?: number},\n): void => {\n if (isNullish(document)) {\n return;\n }\n\n let newCookie = name + '=' + value + '; path=/';\n\n if (attributes?.domain) {\n newCookie += `; domain=${attributes.domain}`;\n }\n\n if (attributes?.expires) {\n newCookie += `; expires=${attributes.expires}`;\n }\n\n if (attributes?.maxAge) {\n newCookie += `; max-age=${attributes.maxAge}`;\n }\n\n try {\n document.cookie = newCookie;\n } catch (_error) {\n logger.log('failed to set cookie object on document', _error);\n return;\n }\n};\n\n/**\n * Delete a cookie by name\n * @see https://www.w3schools.com/js/js_cookies.asp\n */\nexport const deleteCookie = (name: string): void => {\n if (isNullish(document)) {\n return;\n }\n\n try {\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;\n } catch (_error) {\n logger.log('failed to delete cookies from document', _error);\n return;\n }\n};\n","function getGlobalThis(): typeof globalThis {\n // eslint-disable-next-line no-restricted-globals\n if (typeof globalThis !== 'undefined') return globalThis;\n // eslint-disable-next-line unicorn/prefer-global-this\n if (typeof window !== 'undefined') return window as any;\n // eslint-disable-next-line unicorn/prefer-global-this\n if (typeof global !== 'undefined') return global as any;\n // eslint-disable-next-line unicorn/prefer-global-this\n if (typeof self !== 'undefined') return self as any;\n throw new Error('Unable to locate global object');\n}\n\n/**\n * Provides a safe reference to the global object APIs across all environments.\n *\n * `globalThis` is a standard built-in JavaScript object that always refers to the global object of the current\n * environment, regardless of whether your code runs in a browser, Node.js, a worker, or a module.\n *\n * But `globalThis` was introduced in ES2020, and older platforms like Tizen 2016 (Chromium ~2015-2016) do not support\n * it. Rather than bundling a full polyfill into the library, this helper resolves the global object at runtime by\n * checking the available global references in order: `globalThis` → `window` → `global` → `self`.\n *\n * This improves:\n * - compatibility with various environments where the `window` global variable may not be available (VegaOS, React Native)\n * - testability by allowing easy mocking of global object functionality.\n */\nexport const globalScope = getGlobalThis();\n","import {globalScope} from './globalScope';\nimport {isNumber} from './numberUtils';\nimport {isValidString} from './stringUtils';\nimport {isFunction, isNullish} from './Utils';\n\n/**\n * Get `globalScope.devicePixelRatio` (defaults to `1` if not available)\n */\nexport const getGlobalDevicePixelRatio = (): number => {\n if (isNullish(globalScope.devicePixelRatio)) {\n return 1;\n }\n return globalScope.devicePixelRatio > 0 ? globalScope.devicePixelRatio : 1;\n};\n\n/**\n * Get `globalScope.screen` dimensions with {@link getGlobalDevicePixelRatio} applied\n */\nexport const getGlobalScreenDimensions = (): {height: number; scale: number; width: number} | undefined => {\n if (isNullish(globalScope.screen)) {\n return undefined;\n }\n\n if (!isNumber(globalScope.screen.width) || !isNumber(globalScope.screen.height)) {\n return undefined;\n }\n\n const scale = getGlobalDevicePixelRatio();\n const width = globalScope.screen.width * scale;\n const height = globalScope.screen.height * scale;\n\n if (!isFinite(width) || !isFinite(height) || width <= 0 || height <= 0) {\n return undefined;\n }\n\n return {width, height, scale};\n};\n\n/**\n * Add global event listener\n *\n * Use this for window-level events that relate to the browser viewport/tab:\n * - resize: viewport size changes\n * - scroll: page scroll (when listening at window level)\n * - load/unload/beforeunload: page lifecycle\n * - focus/blur: window/tab focus state\n * - hashchange/popstate: navigation events\n * - storage: localStorage changes from other tabs\n *\n * Note: Events bubble up from target → document → window, so window receives\n * many events that also fire on document, but not vice versa.\n */\nexport const addGlobalEventListener = (event: string, handler: EventListenerOrEventListenerObject): void => {\n if (isNullish(globalScope.addEventListener) || !isFunction(globalScope.addEventListener) || isNullish(handler)) {\n return;\n }\n // any-wrap needed to not confirm to type checks\n // we use vendor-prefixed events that are not part of the interface\n globalScope.addEventListener(event, handler);\n};\n\n/**\n * Remove global event listener\n *\n * @see addWindowEventListener for details on when to use window vs document event listeners\n */\nexport const removeGlobalEventListener = (event: string, handler: EventListenerOrEventListenerObject): void => {\n if (\n isNullish(globalScope.removeEventListener) ||\n !isFunction(globalScope.removeEventListener) ||\n isNullish(handler)\n ) {\n return;\n }\n\n // any-wrap needed to not confirm to type checks\n // we use vendor-prefixed events that are not part of the interface\n globalScope.removeEventListener(event, handler);\n};\n\n/**\n * Get `globalScope.location.hostname`\n */\nexport const getGlobalLocationHostname = (): string | undefined => {\n if (isNullish(globalScope.location)) {\n return undefined;\n }\n\n if (!isValidString(globalScope.location.hostname)) {\n return undefined;\n }\n\n return globalScope.location.hostname;\n};\n\n/**\n * Get `globalScope.location.pathname`\n */\nexport const getGlobalLocationPathname = (): string | undefined => {\n if (isNullish(globalScope.location)) {\n return undefined;\n }\n\n if (!isValidString(globalScope.location.pathname)) {\n return undefined;\n }\n\n return globalScope.location.pathname;\n};\n\n/**\n * Get `globalScope.performance.now()` or `undefined` if not available\n *\n * Note: `performance.now()` is preferred over `Date.now()` for measuring time intervals because it provides higher\n * precision and is not affected by changes to the system clock.\n */\nexport const getGlobalPerformanceNow = (): DOMHighResTimeStamp | undefined => {\n if (isNullish(globalScope.performance?.now) || !isFunction(globalScope.performance.now)) {\n return undefined;\n }\n\n // performance.now() returns a DOMHighResTimeStamp, which is a number representing milliseconds with microsecond precision\n return globalScope.performance.now();\n};\n\n/**\n * Get from `global object` the WebOS-specific API objects (for WebOS TV support)\n */\nexport const getGlobalWebOSApi = (): {PalmSystem?: any; webOSSystem?: any} => {\n return {\n webOSSystem: globalScope.webOSSystem,\n PalmSystem: globalScope.PalmSystem,\n };\n};\n\n/**\n * Check if WebOS API is available (for WebOS TV support)\n */\nexport const hasGlobalWebOSApi = (): boolean => {\n const {webOSSystem, PalmSystem} = getGlobalWebOSApi();\n return !isNullish(webOSSystem) || !isNullish(PalmSystem);\n};\n\n/**\n * Get `globalScope.navigator.language` (with fallback to `globalScope.navigator.userLanguage` for IE)\n */\nexport const getGlobalNavigatorLanguage = (): string | undefined => {\n if (isNullish(globalScope.navigator)) {\n return undefined;\n }\n\n return globalScope.navigator.language || (globalScope.navigator as any).userLanguage;\n};\n\n/**\n * Get `globalScope.navigator.product`\n */\nexport const getGlobalNavigatorProduct = (): string | undefined => {\n if (isNullish(globalScope.navigator)) {\n return undefined;\n }\n\n // navigator.product is deprecated, but it remains the standard way to detect some environments like React Native\n return globalScope.navigator.product;\n};\n\n/**\n * Get `globalScope.navigator.userAgent`\n */\nexport const getGlobalNavigatorUserAgent = (): string | undefined => {\n if (isNullish(globalScope.navigator) || !isValidString(globalScope.navigator.userAgent)) {\n return undefined;\n }\n\n return globalScope.navigator.userAgent;\n};\n\n/**\n * Get `globalScope.videojs.VERSION`\n */\nexport const getGlobalVideojsVersion = (): string | undefined => {\n if (isNullish(globalScope.videojs)) {\n return undefined;\n }\n\n return globalScope.videojs['VERSION'];\n};\n\n/**\n * Get `globalScope.THEOplayer.VERSION`\n */\nexport const getGlobalTheoPlayerVersion = (): string | undefined => {\n if (isNullish(globalScope.THEOplayer)) {\n return undefined;\n }\n\n return globalScope.THEOplayer.version;\n};\n","import {isFunction, isNullish} from './Utils';\n\n/**\n * @returns {value is number} `true` if the given value is {@link isNotNullish} and is type of `number`.\n */\nexport const isNumber = (value: unknown): value is number => !isNullish(value) && typeof value === 'number';\n\n/**\n * Checks if a value is a finite number (not NaN, not Infinity, and not -Infinity).\n *\n * This function should be used instead of directly calling `Number.isFinite` or the global `isFinite`\n * because it provides ES5 compatibility and proper type checking.\n *\n * **Why not use `Number.isFinite` directly?**\n * `Number.isFinite` is an ES6 method and does not exist in ES5 environments. Calling it directly\n * would throw a `TypeError` at runtime in older environments.\n *\n * **Key difference between `Number.isFinite` and global `isFinite`:**\n * - `Number.isFinite(value)` does NOT coerce the value — it returns `true` only if the value is\n * already a number and is finite. For example, `Number.isFinite(\"123\")` returns `false`.\n * - Global `isFinite(value)` DOES coerce the value to a number before checking. For example,\n * `isFinite(\"123\")` returns `true` because `\"123\"` is coerced to `123`.\n *\n * This function avoids the coercion risk by first checking the type with `isNumber`, making both\n * implementations behave consistently regardless of the environment.\n *\n * @param value - The value to check\n * @returns `true` if the value is a finite number, `false` otherwise (including NaN, Infinity, -Infinity, null, undefined, or non-numeric types)\n *\n * @example\n * isFiniteNumber(123) // true\n * isFiniteNumber(0) // true\n * isFiniteNumber(-456.78) // true\n * isFiniteNumber(NaN) // false\n * isFiniteNumber(Infinity) // false\n * isFiniteNumber(-Infinity) // false\n * isFiniteNumber(\"123\") // false (string, not coerced)\n * isFiniteNumber(null) // false\n * isFiniteNumber(undefined) // false\n */\nexport const isFiniteNumber = (value: unknown): value is number => {\n if (!isNumber(value)) {\n return false;\n }\n\n // our target is ES5, so we can't use Number.isFinite without checking for it\n if (isFunction(Number.isFinite)) {\n return Number.isFinite(value);\n }\n\n // Fallback implementation for environments that do not support Number.isFinite\n return isFinite(value);\n};\n\n/**\n * Converts a string to an integer using native `parseInt` and returns `undefined` if the result is not a finite number\n */\nexport const parseIntOrUndefined = (value: string): number | undefined => {\n const result = parseInt(value, 10);\n return isFiniteNumber(result) ? result : undefined;\n};\n","import {logger} from './Logger';\n\n/** Polyfill for ES2017 'Object.values' */\nexport const objectValues = (obj: any) => {\n return Object.keys(obj).map(function (key) {\n return obj[key];\n });\n};\n\n/**\n * Wraps property access with try/catch\n */\nexport function safeAccess<T>(access: () => T): T | undefined {\n try {\n return access();\n } catch (error) {\n logger.log(`safeAccess catched failed access on property: `, error);\n return undefined;\n }\n}\n","import {SSAI_RELATED_SAMPLE_MARKER} from '../core/ssai/ssaiUtils';\nimport type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\n\nimport {getGlobalLocationPathname} from './globalScopeUtils';\nimport {isValidString} from './stringUtils';\nimport * as Utils from './Utils';\nimport {isNullish, removeTrailingSlash} from './Utils';\n\n/**\n * Clear all \"state\" values from the sample (all values that describe \"playing sample\", \"startup sample\" ...).\n */\nexport function clearSampleStateValues(sample: Sample): void {\n sample.ad = 0;\n sample.adId = undefined;\n sample.adIndex = undefined;\n sample.adPosition = undefined;\n sample.adSystem = undefined;\n sample.autoplay = undefined;\n sample.buffered = 0;\n sample.castTech = undefined;\n sample.completed = undefined;\n sample.drmLoadTime = undefined;\n sample.droppedFrames = 0;\n sample.duration = 0;\n sample.errorCode = undefined;\n sample.errorData = undefined;\n sample.errorMessage = undefined;\n sample.errorSegments = undefined;\n sample.errorSeverity = undefined;\n sample.isProgramChange = undefined;\n sample.pageLoadTime = 0;\n sample.paused = 0;\n sample.played = 0;\n sample.playerStartupTime = 0;\n sample.seeked = 0;\n sample.startupTime = 0;\n sample.state = undefined;\n sample.videoStartFailed = undefined;\n sample.videoStartFailedReason = undefined;\n sample.videoStartupTime = 0;\n\n sample[SSAI_RELATED_SAMPLE_MARKER] = undefined;\n}\n\nexport function getDefaultSamplePath(): string | undefined {\n const pathname = getGlobalLocationPathname();\n return isValidString(pathname) ? removeTrailingSlash(pathname) : undefined;\n}\n\nexport function buildAdSample(sample?: Sample): AdSample {\n const adSample: AdSample = {\n platform: 'web',\n };\n\n if (isNullish(sample)) {\n return adSample;\n }\n\n adSample.cdnProvider = sample.cdnProvider;\n adSample.customUserId = sample.customUserId;\n adSample.domain = sample.domain;\n adSample.key = sample.key;\n adSample.language = sample.language;\n adSample.path = sample.path;\n adSample.player = sample.player;\n adSample.playerKey = sample.playerKey;\n adSample.playerTech = sample.playerTech;\n adSample.screenHeight = sample.screenHeight;\n adSample.screenWidth = sample.screenWidth;\n adSample.size = sample.size;\n adSample.userAgent = sample.userAgent;\n adSample.userId = sample.userId;\n adSample.version = sample.version;\n adSample.videoId = sample.videoId;\n adSample.videoImpressionId = sample.impressionId;\n adSample.videoTitle = sample.videoTitle;\n adSample.videoWindowHeight = sample.videoWindowHeight;\n adSample.videoWindowWidth = sample.videoWindowWidth;\n\n Utils.transferCustomDataFields(sample, adSample);\n adSample.experimentName = sample.experimentName;\n\n return adSample;\n}\n","import {isFunction, isNotNullish, isNullish} from './Utils';\n\nexport const isValidString = (s: unknown): s is string => isNotNullish(s) && typeof s === 'string';\n\nexport const isEmpty = (s: string | null | undefined): boolean => isNullish(s) || s.length === 0;\n\nexport const isBlank = (s: string | null | undefined): boolean => isEmpty(s) || isEmpty(s?.trim());\n\nexport const endsWith = (s: string, suffix: string): boolean => {\n if (!isValidString(s) || !isValidString(suffix)) {\n return false;\n }\n\n // our target is ES5, so we can't use String.prototype.endsWith without checking for it\n if (isFunction(String.prototype.endsWith)) {\n return s.endsWith(suffix);\n }\n\n // Fallback implementation for environments that do not support String.prototype.endsWith\n return s.substring(s.length - suffix.length) === suffix;\n};\n\nexport const startsWith = (s: string, prefix: string): boolean => {\n if (!isValidString(s) || !isValidString(prefix)) {\n return false;\n }\n\n // our target is ES5, so we can't use String.prototype.startsWith without checking for it\n if (isFunction(String.prototype.startsWith)) {\n return s.startsWith(prefix);\n }\n\n // Fallback implementation for environments that do not support String.prototype.startsWith\n return s.substring(0, prefix.length) === prefix;\n};\n","export const generateUUID = (): string => {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","import {BitmovinPwxAnalyticsPackage} from './adapters/bitmovinPwx/BitmovinPwxAnalyticsPackage';\nimport {CdnProvider} from './enums/CDNProvider';\nimport {Player} from './enums/Player';\nimport {VERSION} from './utils/Version';\n\nexport {VERSION as version};\n\nexport type {AnalyticsConfig} from './types/AnalyticsConfig';\n\nexport {Player as Players};\nexport {CdnProvider as CdnProviders};\n\nexport {BitmovinPwxAnalyticsPackage};\n"],"names":["root","factory","exports","module","define","amd","self","StateMachine","VERSION","Result","SUCCEEDED","NOTRANSITION","CANCELLED","PENDING","Error","INVALID_TRANSITION","PENDING_TRANSITION","INVALID_CALLBACK","WILDCARD","ASYNC","create","cfg","target","initial","state","terminal","fsm","events","callbacks","map","transitions","add","e","from","Array","isArray","name","n","length","push","to","event","hasOwnProperty","buildEvent","current","is","indexOf","this","can","transition","undefined","cannot","concat","isFinished","error","args","msg","states","Object","keys","sort","defer","doCallback","func","apply","beforeAnyEvent","afterAnyEvent","leaveAnyState","enterAnyState","changeState","beforeThisEvent","afterThisEvent","leaveThisState","enterThisState","beforeEvent","afterEvent","leaveState","specific","general","enterState","prototype","slice","call","arguments","cancel","leave","context","config","getCurrentImpressionId","analytics","getUserId","setCustomData","values","internalAdapter","setCustomDataOnce","sourceChange","_config","sanitizedConfig","sanitizeAnalyticsConfig","areCollectorRequirementsValid","guardAgainstDuplicatedUserId","BitmovinPwxInternalAdapter","Analytics","dispose","release","version","BitmovinPwxAdapter","onAdd","dependencies","BitmovinPwxAnalyticsPackage","_","baseContext","registry","get","CoreExportNames","CoreEffects","EventListenerEffectFactory","StateEffectFactory","using","logger","BundleExportNames","Logger","source","SourceExportNames","SourceState","playerConfig","PlayerConfig","analyticsConfig","playerKey","key","log","tryJSONStringify","adapter","url","listener","abortSignal","removeEventListener","addEventListener","Constants","CoreStateAtoms","SourcesApiExportNames","SourceEventBus","PlaybackApiEventsPackageExportNames","PlaybackEvent","_name","State","stateMachineCallbacks","playingHeartbeatService","opts","enabledDebugging","debuggingStates","createStateMachine","SETUP","JSM_INITIAL_EVENT","customStateMachineErrorCallback","Event","SOURCE_LOADED","ERROR","READY","on","stayIn","PAUSE","TIMECHANGED","PLAY","STARTUP","PLAYING","END","VIDEOSTART_FAILED","getAllStatesBut","UNLOAD","stopHeartbeat","onleavestate","eventTimestamp","eventData","logStateMachineTransition","addStatesToLog","stateDuration","onEnterStateTimestamp","isStartup","maybeSetOrClearVideoStartTimeouts","startup","toLowerCase","lowerCaseFrom","String","unload","setup","clearVideoStartTimeout","defaultStateMachineCallbackFn","isFunction","logMissingCallbackWarning","startHeartbeat","onenterstate","_eventData","Date","now","isNumber","starttime","_event","_from","_to","_eventTimestamp","timestamp","eventObject","EventDebugging","getStates","setEnabledDebugging","enabled","setVideoStartTimeout","AnalyticsStateMachine","BitmovinPwxAnalyticsStateMachine","onBeforeUnLoadEvent","HeartbeatService","currentTime","stateMachine","setListener","getSource","playback","playhead","position","getAutoPlay","autoplay","getCurrentPlaybackInfo","hls","sourceConfig","resources","filter","v","includes","dash","videoRect","video","element","getBoundingClientRect","videoWidth","Math","round","width","videoHeight","height","streamFormat","StreamTypes","getCommonPlaybackInfo","droppedFrames","isMuted","muted","isLive","stream","type","videoWindowHeight","videoWindowWidth","videoDuration","normalizeVideoDuration","duration","videoPlaybackHeight","videoPlaybackWidth","m3u8Url","mpdUrl","videoCodec","audioCodec","videoBitrate","audioBitrate","getPlayerName","Player","BITMOVIN_PWX","getPlayerTech","getPlayerVersion","Version","initialize","registerEventListeners","registerUnloadEventListeners","ErrorDetailTracking","errorDetailTrackingSettingsProvider","ErrorDetailBackend","collectorConfig","errorDetailSubscribable","handleCollectorUnload","eventCallback","bind","windowEventTracker","sourceEventBus","playbackAtom","Ready","Play","Playing","Paused","TimeChanged","VideoAttached","Ended","abortListener","abortSignalReason","reason","SOURCE_UNLOADED","code","message","data","originalError","InternalAdapter","Utils","CreateSourceStateAtom","CreateSourceReference","SourceReferences","SourceApiManager","VideoElementUtils","onLicenseKeyReceived","EventDispatcher","onLicenseCallFailed","qualityChangeService","ssaiService","SsaiService","defaultStateMachineCallbacks","sourceInfoFallbackService","SourceInfoFallbackService","drmPerformanceInfo","WindowEventTracker","getCurrentTimestamp","resetIntervals","resetSourceRelatedState","callEvent","dimensions","getGlobalScreenDimensions","screenHeight","screenWidth","getDrmPerformanceInfo","getSegmentInfo","getDownloadSpeedInfo","segmentsDownloadCount","segmentsDownloadSize","segmentsDownloadTime","avgDownloadSpeed","minDownloadSpeed","maxDownloadSpeed","avgTimeToFirstByte","resetDownloadSpeedInfoMeasures","previousState","currentState","customDataValues","customdatachange","CUSTOM_DATA_CHANGE","MANUAL_SOURCE_CHANGE","reset","programChange","sourceMetadata","isSsaiActive","isInActiveState","AdQuartile","onAdStarted","_ad","onAdFinished","onAdBreakStarted","_adBreak","onAdBreakFinished","onAdClicked","onAdError","onAdManifestLoaded","onAdQuartile","onAdSkipped","onPlay","onPause","onBeforeUnload","AdCallbacks","REBUFFERING_HEARTBEAT_INTERVALS","videoStartupTimeoutMs","Settings","ANALYTICS_VIDEOSTART_TIMEOUT","rebufferTimeoutMs","ANALYTICS_REBUFFER_TIMEOUT","currentRebufferingIntervalIndex","stateMachineEventMethod","warn","clearRebufferingTimeoutHandle","clearRebufferingHeartbeatHandle","startRebufferingHeartbeatInterval","resetRebufferingHelpers","startRebufferingTimeoutHandle","rebufferingHeartbeatIntervalHandle","setInterval","getTime","heartbeat","buffered","min","isNotNullish","clearInterval","rebufferingTimeoutHandle","setTimeout","ErrorCode","BUFFERING_TIMEOUT_REACHED","additionalData","clearTimeout","videoStartTimeout","VIDEOSTART_TIMEOUT","onHeartbeat","playerCurrentTime","sendPlayingSample","triggeredBySsai","triggeredByProgramChange","setVideoTimeEndFromEvent","payload","played","isProgramChange","SSAI_RELATED_SAMPLE_MARKER","resetCurrentStateStart","stateEnterTimestamp","setVideoTimeStartFromEvent","programChangeTimestamp","updateSourceMetadata","excludedStates","stateEnumObj","getAllStates","s","whileIn","stateMachineEventDefBuilderFn","runEventCallbacksFor","passOver","eventName","errorCode","errorMessage","_ex","loggerMessage","loggerMessageData","ignoreStates","isNullish","find","ignoredState","stateStringEnumObj","objectValues","padRight","isPlaying","adPodPosition","adCallbacks","container","getContainer","viewportTracker","ViewportTracker","onIntersectionChanged","clearCurrentTimeInterval","adManifestDownloadTime","activeAdState","isContainerInViewport","enterViewportTimestamp","timeInViewport","isInViewport","isLinearAdActive","beginPlayingTimestamp","updatePlayingTime","isVmap","sendAnalyticsRequest","buildInitialActiveAdBreakState","adBreakInfo","manifestDownloadTime","adBreak","activeAdBreakState","adStartupTimestamp","resetActiveAd","adInfo","isLinear","buildInitialActiveAdState","adStartupTime","startAd","activeAdStateCopy","completed","completeAd","adDuration","skipped","skipPosition","skipPercentage","calculatePercentage","exitPosition","adBreakSample","transformedError","transformError","severity","errorData","errorSeverity","activeAdId","adId","errorPosition","errorPercentage","adClickthroughUrl","clickThroughUrl","clicked","clickPosition","clickPercentage","quartile","FIRST_QUARTILE","quartile1","MIDPOINT","midpoint","THIRD_QUARTILE","quartile3","closed","closePosition","closePercentage","adSample","buildAdSample","sample","moduleInfo","getAdModuleInfo","analyticsVersion","adModule","adModuleVersion","pageLoadType","getPageLoadType","time","adImpressionId","generateUUID","percentageInViewport","timePlayed","backend","sendAdRequest","started","currentTimeInterval","calculateTime","max","AdAnalytics","TIMEOUT_CURRENT_TIME_INTERVAL","playPercentage","MODULE_NAME","adFallbackIndex","adIdPlayer","id","adReplaceContentDuration","calculateTimeWithUndefined","replaceContentDuration","adIsPersistent","persistent","adTagType","tagType","adTagUrl","tagUrl","adPreloadOffset","preloadOffset","fallbackIndex","adPosition","adOffset","URL","adTagServer","hostname","adTagPath","pathname","isFiniteNumber","scheduleTime","adScheduleTime","mediaUrl","adPlaybackHeight","adPlaybackWidth","mimeType","mediaPath","mediaServer","bitrate","vastData","adSystem","advertiserName","apiFramework","creativeAdId","creativeId","universalAdIdRegistry","universalAdIdValue","adDescription","minSuggestedDuration","surveyUrl","adTitle","wrapperAdsCount","skippableAfter","adSkipAfter","adSkippable","skippable","initialAnalyticsConfig","backendFactory","sessionHandler","featureManager","onErrorDetailEventDispatcher","identicalErrorReportingLimiter","hasSentStartupSample","droppedSampleFrames","playerStartupTime","authenticationCallback","authenticationCompleted","success","featureConfigs","configureFeatures","guardConfigChangeAgainstMissingTitle","guardConfigChangeAgainstMissingIsLive","newConfig","mergeAnalyticsConfig","oldConfig","setState","sendSample","setConfigParameters","setAutoDetectedDeviceInformation","impressionId","userId","changeCustomData","extractCustomDataFieldsOnly","SessionPersistenceHandler","that","domain","getDomainFromAnalyticsConfig","licenseKey","licenseKeyReceivedUnsubscriber","subscribe","eventArgs","buildInitialSample","init","setupStateMachineCallbacks","features","registerFeatures","adAnalytics","supportsDeferredLicenseLoading","isValidString","isBlank","debug","resetFeatures","createBackend","videoCompletionTracker","resetValues","errorMessageToUser","player","deviceInformation","getDeviceInformationFromAnalyticsConfig","cdnProvider","videoId","videoTitle","title","customUserId","transferCustomDataFields","experimentName","model","hasGlobalWebOSApi","modelName","getWebOSTVModelName","setDuration","navigationStart","globalScope","performance","timing","pageLoadTime","supportedVideoCodecs","CodecHelper","supportedVideoFormats","sanitizeVideoStartupTime","videoStartupTime","startupTime","drmPerformance","drmType","drmLoadTime","setStartupHasFinished","applySourceMetadataToAnalyticsConfig","path","getDefaultSamplePath","playing","setCompletionValues","videoStartForClosedState","videoTimeStart","videoTimeEnd","sendUnloadRequest","clearSampleStateValues","setVideoTimeStart","setVideoTimeEnd","heartbeatPayload","qualitychange","startResetInterval","increaseCounter","hasExceededQualityChangeThreshold","QUALITY_CHANGE_THRESHOLD_EXCEEDED","legacyData","updateSampleQualityInfo","codec","audiotrack_changing","pause","paused","seeking","seeked","rebuffering","videoStartFailed","videoStartFailedReason","VideoStartFailedReason","PLAYER_ERROR","TIMEOUT","VIDEO_STARTUP_TIMEOUT_REACHED","dispatch","shouldReportError","errorSegments","onError","ad","AD_TYPE","CSAI","mute","unMute","subtitle_changing","analyticsEventBase","manualSourceChange","initialSourceChange","end","NoOpBackend","stopResetInterval","_duration","_state","setPlaybackInfoFromAdapter","info","size","playerTech","progUrl","isBoolean","isCasting","castTech","audioLanguage","subtitleEnabled","subtitleLanguage","customDataOnceValues","downloadSpeedInfo","manipulate","setQualityInfoOnSample","copySample","sendRequest","sendSsaiEngagementAdSample","ssaiEngagementTrackingEnabled","isSsaiEngagementStartedData","ssaiAdSample","createStartedAdSample","isSsaiEngagementQuartileData","createQuartileAdSample","isSsaiEngagementErrorData","analyticsError","ssaiErrorAdSample","createErrorAdSample","addWatched","start","completedTotal","getCompletionPercentage","Number","isNaN","value","errorTransformerCallback","transform","isErrorSeverity","screenDimensions","language","getGlobalNavigatorLanguage","platform","PlayerSize","Window","userAgent","getGlobalNavigatorUserAgent","BackendFactory","FeatureManager","IdenticalErrorReportingLimiter","playbackInfo","licensingRequest","isEnabled","inner","createInnerBackend","decorateWithDebuggingBackend","DebuggingBackend","decorateWithBackendFromConfigIfAvailable","innerBackend","wrapBackend","backendUrl","ANALYTICS_BACKEND_BASE_URL","LicenseCheckingBackend","LicenseCall","sequenceNumberAssigningBackend","SequenceNumberBackend","LongPlaytimeFilteringBackend","underlying","fields","debugFields","printFields","sendRequestSynchronous","forEach","f","table","callback","unsubscribe","index","splice","DEFAULT_HEARTBEAT_INTERVAL_MS","getPlayerCurrentTime","heartbeatInterval","clearHeartbeat","_currentErrorCount","_lastErrorCode","_lastErrorSeverity","MAX_IDENTICAL_ERROR_REPORTING","licenseCall","backendBaseUrl","licenseKeyReceived","licenseLazyLoadingTimeoutHandle","unsubscribeFromAdapter","promise","wrapLicenseCheckPromiseWithCallback","performLicenseCheck","licenseCallFailed","licenseLazyLoadingTimeout","QueueBackend","ANALYTICS_LICENSECALL_TIMEOUT","status","LicensingResult","Denied","Promise","resolve","then","result","Granted","remoteBackend","RemoteBackend","flushTo","catch","err","response","next","nextBackend","isPlayedAboveThreshold","_sample","_adSample","qualityChangeCountThreshold","ANALYTICS_QUALITY_CHANGE_COUNT_THRESHOLD","qualityChangeCount","previousVideoBitrate","previousAudioBitrate","startupHasFinished","QUALITY_CHANGE_COUNT_THRESHOLD","startupVideoBitrate","startupAudioBitrate","shouldAllowVideoQualityChange","newBitrate","setVideoBitrate","shouldAllowAudioQualityChange","setAudioBitrate","qualityChangeCountResetIntervalId","ANALYTICS_QUALITY_CHANGE_COUNT_RESET_INTERVAL","queue","unloadQueue","syncQueue","adQueue","analyticsCall","AnalyticsCall","noOp","sequenceNumber","updateSampleBeforeSending","isSequenceNumberAboveThreshold","SEQUENCE_NUMBER_LIMIT","COOKIE_NAME_BITMOVIN_ANALYTICS_UUID","COOKIE_DEFAULT_MAX_AGE","cookiesEnabled","deleteCookie","existingUserId","getCookie","cookieDomain","validateCookieDomainValue","cookiesDomain","cookieMaxAge","validateCookieMaxAgeValue","cookiesMaxAge","nowMillis","cookieExpires","toUTCString","setCookie","expires","maxAge","encodeURIComponent","setStreamFormat","applyStreamFormat","applyAndStoreCodecInfo","codecInfo","SsaiState","eventHandler","adIndex","IDLE","isFirstSampleOfAd","sentAdQuartiles","errorSent","activate","adBreakStart","adBreakMetadata","isActivated","AD_BREAK_STARTED","currentAdMetadata","adStart","adMetadata","reportPlaybackInteraction","ACTIVE","resetAdData","customData","currentAdImpressionId","timestampOfAdStart","getCurrentMonotonicTimestampInMs","reportEngagementInteraction","adQuartileFinished","adQuartile","adQuartileMetadata","quartileMetadata","timeSinceAdStartedInMs","getMonotonicTimestampInMsSince","adBreakEnd","resetAdBreakData","SSAI","customDataValuesKeys","sendAdEngagementErrorSample","adType","ROUTING_URL_PARAM","ROUTING_URL_PARAM_VALUE_SSAI","playbackSample","ssaiEngagementErrorData","ssaiEngagementStartedData","ssaiEngagementQuartileData","timestampInMs","adEngagementSample","customData1","customData2","customData3","customData4","customData5","customData6","customData7","customData8","customData9","customData10","customData11","customData12","customData13","customData14","customData15","customData16","customData17","customData18","customData19","customData20","customData21","customData22","customData23","customData24","customData25","customData26","customData27","customData28","customData29","customData30","customData31","customData32","customData33","customData34","customData35","customData36","customData37","customData38","customData39","customData40","customData41","customData42","customData43","customData44","customData45","customData46","customData47","customData48","customData49","customData50","customData51","customData52","customData53","customData54","customData55","customData56","customData57","customData58","customData59","customData60","customData61","customData62","customData63","customData64","customData65","customData66","customData67","customData68","customData69","customData70","customData71","customData72","customData73","customData74","customData75","customData76","customData77","customData78","customData79","customData80","customData81","customData82","customData83","customData84","customData85","customData86","customData87","customData88","customData89","customData90","customData91","customData92","customData93","customData94","customData95","customData96","customData97","customData98","customData99","customData100","videoImpressionId","quartile1FailedBeaconUrl","failedBeaconUrl","midpointFailedBeaconUrl","quartile3FailedBeaconUrl","completedFailedBeaconUrl","performanceNow","getGlobalPerformanceNow","floor","CdnProvider","BITMOVIN_PLAYER_LICENSING_ERROR","SETUP_MISSING_LICENSE_WHITELIST","urlPath","split","endsWith","MIMETypes","HLS","MP4","WEBM","DASH","PAGE_LOAD_TYPE","prog","stateMachineEvent","PAGE_CLOSED","UNKNOWN","_isEnabled","disable","disabled","configure","authenticated","configContainer","extractConfig","configured","Feature","unregisterFeatures","feature","constructor","_queue","_enabled","joinUrls","copyErrorDetailTruncateStringsAndUrls","errorDetail","maxStringLength","maxUrlLength","substr","copyErrorDataTruncateStrings","httpRequests","request","copyHttpRequestTruncateUrls","httpRequest","maxLength","lastRedirectLocation","exceptionMessage","copyErrorDetailTruncateHttpRequests","maxRequests","limitHttpRequestsOfQueuedErrorDetails","send","errorDetailCopy","MAX_STRING_LENGTH","MAX_URL_LENGTH","post","flush","copy","shift","removeFromQueue","clear","findIndex","settingsProvider","subscribables","httpRequestTracking","errorIndex","onErrorHandler","httpRequestsCopy","errorId","exceptionStacktrace","subscribable","_authenticated","numberOfHttpRequests","errorDetails","customDataFieldCount","i","match","input","retVal","sanitizeCustomDataValues","extracted","sanitizedCustomDataValues","getCustomDataString","playerVideoDuration","Infinity","streamType","streamUrl","DEFAULT_RESULT","startCasting","casting","muting_ready","baseUrl","analyticsServerUrl","adAnalyticsServerUrl","analyticsUrl","isSsaiRelatedSample","appendSsaiRoutingParam","trySendBeacon","fallbackFunction","requestHeaders","navigator","sendBeacon","blob","Blob","JSON","stringify","adAnalyticsUrl","videoFormatCodecMap","avc","vp9","av1","hevc","MediaSource","isTypeSupported","getOwnPropertyNames","format","some","body","async","isReactNative","xhttp","isLegacyXDomainRequestUsed","XDomainRequest","XMLHttpRequest","responseCallback","readyState","DONE","responseText","sampleResponse","parse","onload","onreadystatechange","open","setRequestHeader","licenseServerUrl","getInstance","instance","analyticsDebugConfig","console","optionalParams","tabularData","properties","str","join","MESSAGE_NAMESPACE","ANALYTICS_MIN_SEEK_DIFFERENCE_THRESHOLD","anything","isDocumentHidden","BACKGROUND","FOREGROUND","toString","toBoolean","Boolean","valueOf","isObject","isPlainObject","removeTrailingSlash","replace","timeInSeconds","fromConfig","toConfig","CustomDataUtils","customDataField","numerator","denominator","getURLResourceName","pop","reduce","prev","startsWith","getGlobalNavigatorProduct","isAudioMuted","playerIsMuted","playerVolume","obj","threshold","inViewport","options","rootMargin","observer","IntersectionObserver","entries","handleIntersect","observe","_error","hiddenPropertyName","getDocumentPropertyWithPrefix","visibilityChange","addDocumentEventListener","handleVisibilityChange","isHidden","document","unobserve","disconnect","removeDocumentEventListener","_observer","intersectionRatio","getGlobalWebOSApi","webOSSystem","PalmSystem","deviceInfo","trackedObjects","addGlobalEventListener","removeGlobalEventListener","deviceType","deviceClass","getGlobalLocationHostname","fallbackDomain","origin","oldConfigWithoutSourceRelatedFields","sourceSpecificProperties","customDataFieldsRegex","removeSourceRelatedFields","mergedCollectorConfig","oldCollectorConfig","newCollectorConfig","mergeCollectorConfig","errorMessages","isDomainMissing","fullErrorMessage","prop","pascalCase","charAt","toUpperCase","prefixedProp","hiddenProp","isVideoInFullscreen","fullscreenProp","nodeName","handler","allCookies","cookie","cookieName","substring","attributes","newCookie","globalThis","window","g","getGlobalThis","getGlobalDevicePixelRatio","devicePixelRatio","screen","scale","isFinite","location","getGlobalLocationPathname","userLanguage","product","getGlobalVideojsVersion","videojs","getGlobalTheoPlayerVersion","THEOplayer","parseIntOrUndefined","parseInt","access","isEmpty","trim","suffix","prefix","c","r","random","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","Function"],"sourceRoot":""}
1
+ {"version":3,"file":"bitmovin-analytics-bitmovin-player-web-x.js","mappings":"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cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,eACA,gBAEA,kBAMW,EAAA8L,qBAAuB,EAAA9L,qBAAqB5pB,QAAO,SAAC21B,GAAM,OAAAA,EAAEC,MAAM,iBAAR,IAA2BvhC,OAKrF,EAAA2iB,4BAA8B,SAAC6e,GAC1C,IAAMC,EAA2B,CAAC,EAMlC,OALA,EAAAlM,qBAAqB9H,SAAQ,SAAC9nB,GACxB67B,EAAM77B,KACR87B,EAAO97B,GAAO67B,EAAM77B,GAExB,IACO87B,CACT,EAEa,EAAAC,yBAA2B,SAACjvB,GACvC,IAAMkvB,GAAY,IAAAhf,6BAA4BlQ,GAExCmvB,EAA8C,CAAC,EAMrD,OALA,IAAAjd,0BAAyBgd,EAAWC,GAGpCA,EAA0Bhd,gBAAiB,IAAAid,qBAAoBF,EAAU/c,gBAElEgd,CACT,C,kCC1OA,IAAYvS,E,0EAAZ,SAAYA,GACV,kBACA,oBACA,aACD,CAJD,CAAYA,IAAe,kBAAfA,EAAe,I,qFCyB3B,kCAAuCyS,GAGrC,IAAI,IAAAhqB,WAAUgqB,IAAwB1W,OAAOC,MAAMyW,IAAwBA,IAAwBC,IACjG,OAAO,EAET,OAAOD,CACT,EAEA,6CACEE,EACAC,GAEA,IAAMC,EAAiB,CAErBz1B,aAAcu1B,QAAAA,OAAcphC,EAK5B4oB,QAASyY,GAGX,IAAI,IAAAnqB,WAA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","sources":["webpack://bitmovin.analytics/webpack/universalModuleDefinition","webpack://bitmovin.analytics/./node_modules/javascript-state-machine/state-machine.js","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/BitmovinPwxAdapter.ts","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/BitmovinPwxAnalyticsPackage.ts","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/BitmovinPwxAnalyticsStateMachine.ts","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/BitmovinPwxInternalAdapter.ts","webpack://bitmovin.analytics/./src/adapters/bitmovinPwx/ExportNames.ts","webpack://bitmovin.analytics/./src/adapters/internal/InternalAdapter.ts","webpack://bitmovin.analytics/./src/adapters/internal/ads/AdModuleAPI.ts","webpack://bitmovin.analytics/./src/analyticsStateMachines/AnalyticsStateMachine.ts","webpack://bitmovin.analytics/./src/analyticsStateMachines/stateMachineUtils.ts","webpack://bitmovin.analytics/./src/core/AdAnalytics.ts","webpack://bitmovin.analytics/./src/core/Analytics.ts","webpack://bitmovin.analytics/./src/core/BackendFactory.ts","webpack://bitmovin.analytics/./src/core/DebuggingBackend.ts","webpack://bitmovin.analytics/./src/core/EventDispatcher.ts","webpack://bitmovin.analytics/./src/core/HeartbeatService.ts","webpack://bitmovin.analytics/./src/core/IdenticalErrorReportingLimiter.ts","webpack://bitmovin.analytics/./src/core/LicenseCheckingBackend.ts","webpack://bitmovin.analytics/./src/core/LongPlaytimeFilteringBackend.ts","webpack://bitmovin.analytics/./src/core/NoOpBackend.ts","webpack://bitmovin.analytics/./src/core/QualityChangeService.ts","webpack://bitmovin.analytics/./src/core/QueueBackend.ts","webpack://bitmovin.analytics/./src/core/RemoteBackend.ts","webpack://bitmovin.analytics/./src/core/SequenceNumberBackend.ts","webpack://bitmovin.analytics/./src/core/SessionPersistenceHandler.ts","webpack://bitmovin.analytics/./src/core/SourceInfoFallbackService.ts","webpack://bitmovin.analytics/./src/core/ssai/SsaiService.ts","webpack://bitmovin.analytics/./src/core/ssai/ssaiEngagementInteractionData.ts","webpack://bitmovin.analytics/./src/core/ssai/ssaiUtils.ts","webpack://bitmovin.analytics/./src/enums/AdType.ts","webpack://bitmovin.analytics/./src/enums/CDNProvider.ts","webpack://bitmovin.analytics/./src/enums/ErrorCode.ts","webpack://bitmovin.analytics/./src/enums/Event.ts","webpack://bitmovin.analytics/./src/enums/MIMETypes.ts","webpack://bitmovin.analytics/./src/enums/PageLoadType.ts","webpack://bitmovin.analytics/./src/enums/Player.ts","webpack://bitmovin.analytics/./src/enums/PlayerSize.ts","webpack://bitmovin.analytics/./src/enums/StreamTypes.ts","webpack://bitmovin.analytics/./src/enums/VideoStartFailedReason.ts","webpack://bitmovin.analytics/./src/features/Feature.ts","webpack://bitmovin.analytics/./src/features/FeatureManager.ts","webpack://bitmovin.analytics/./src/features/errordetails/ErrorDetailBackend.ts","webpack://bitmovin.analytics/./src/features/errordetails/ErrorDetailTracking.ts","webpack://bitmovin.analytics/./src/types/CustomDataValues.ts","webpack://bitmovin.analytics/./src/types/LicensingRequest.ts","webpack://bitmovin.analytics/./src/types/PlaybackInfo.ts","webpack://bitmovin.analytics/./src/types/StateMachineCallbacks.ts","webpack://bitmovin.analytics/./src/utils/AnalyticsCall.ts","webpack://bitmovin.analytics/./src/utils/CodecHelper.ts","webpack://bitmovin.analytics/./src/utils/EventDebugging.ts","webpack://bitmovin.analytics/./src/utils/Http.ts","webpack://bitmovin.analytics/./src/utils/LicenseCall.ts","webpack://bitmovin.analytics/./src/utils/Logger.ts","webpack://bitmovin.analytics/./src/utils/Settings.ts","webpack://bitmovin.analytics/./src/utils/Utils.ts","webpack://bitmovin.analytics/./src/utils/Version.ts","webpack://bitmovin.analytics/./src/utils/ViewportTracker.ts","webpack://bitmovin.analytics/./src/utils/WebOSUtils.ts","webpack://bitmovin.analytics/./src/utils/WindowEventTracker.ts","webpack://bitmovin.analytics/./src/utils/analyticsConfigUtils.ts","webpack://bitmovin.analytics/./src/utils/collectorRequirementChecks.ts","webpack://bitmovin.analytics/./src/utils/documentUtils.ts","webpack://bitmovin.analytics/./src/utils/globalScope.ts","webpack://bitmovin.analytics/./src/utils/globalScopeUtils.ts","webpack://bitmovin.analytics/./src/utils/numberUtils.ts","webpack://bitmovin.analytics/./src/utils/objectUtils.ts","webpack://bitmovin.analytics/./src/utils/sampleUtils.ts","webpack://bitmovin.analytics/./src/utils/stringUtils.ts","webpack://bitmovin.analytics/./src/utils/uuidUtils.ts","webpack://bitmovin.analytics/webpack/bootstrap","webpack://bitmovin.analytics/webpack/runtime/global","webpack://bitmovin.analytics/./src/bitmovin-analytics-bitmovin-player-web-x.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"bitmovin\"] = factory();\n\telse\n\t\troot[\"bitmovin\"] = root[\"bitmovin\"] || {}, root[\"bitmovin\"][\"analytics\"] = factory();\n})(self, function() {\nreturn ","/*\n\n Javascript State Machine Library - https://github.com/jakesgordon/javascript-state-machine\n\n Copyright (c) 2012, 2013, 2014, 2015, Jake Gordon and contributors\n Released under the MIT license - https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE\n\n*/\n\n(function () {\n\n var StateMachine = {\n\n //---------------------------------------------------------------------------\n\n VERSION: \"2.4.0\",\n\n //---------------------------------------------------------------------------\n\n Result: {\n SUCCEEDED: 1, // the event transitioned successfully from one state to another\n NOTRANSITION: 2, // the event was successfull but no state transition was necessary\n CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback\n PENDING: 4 // the event is asynchronous and the caller is in control of when the transition occurs\n },\n\n Error: {\n INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state\n PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending\n INVALID_CALLBACK: 300 // caller provided callback function threw an exception\n },\n\n WILDCARD: '*',\n ASYNC: 'async',\n\n //---------------------------------------------------------------------------\n\n create: function(cfg, target) {\n\n var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false }\n var terminal = cfg.terminal || cfg['final'];\n var fsm = target || cfg.target || {};\n var events = cfg.events || [];\n var callbacks = cfg.callbacks || {};\n var map = {}; // track state transitions allowed for an event { event: { from: [ to ] } }\n var transitions = {}; // track events allowed from a state { state: [ event ] }\n\n var add = function(e) {\n var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified\n map[e.name] = map[e.name] || {};\n for (var n = 0 ; n < from.length ; n++) {\n transitions[from[n]] = transitions[from[n]] || [];\n transitions[from[n]].push(e.name);\n\n map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified\n }\n if (e.to)\n transitions[e.to] = transitions[e.to] || [];\n };\n\n if (initial) {\n initial.event = initial.event || 'startup';\n add({ name: initial.event, from: 'none', to: initial.state });\n }\n\n for(var n = 0 ; n < events.length ; n++)\n add(events[n]);\n\n for(var name in map) {\n if (map.hasOwnProperty(name))\n fsm[name] = StateMachine.buildEvent(name, map[name]);\n }\n\n for(var name in callbacks) {\n if (callbacks.hasOwnProperty(name))\n fsm[name] = callbacks[name]\n }\n\n fsm.current = 'none';\n fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); };\n fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); }\n fsm.cannot = function(event) { return !this.can(event); };\n fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); };\n fsm.isFinished = function() { return this.is(terminal); };\n fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17)\n fsm.states = function() { return Object.keys(transitions).sort() };\n\n if (initial && !initial.defer)\n fsm[initial.event]();\n\n return fsm;\n\n },\n\n //===========================================================================\n\n doCallback: function(fsm, func, name, from, to, args) {\n if (func) {\n try {\n return func.apply(fsm, [name, from, to].concat(args));\n }\n catch(e) {\n return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, \"an exception occurred in a caller-provided callback function\", e);\n }\n }\n },\n\n beforeAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbeforeevent'], name, from, to, args); },\n afterAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafterevent'] || fsm['onevent'], name, from, to, args); },\n leaveAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleavestate'], name, from, to, args); },\n enterAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenterstate'] || fsm['onstate'], name, from, to, args); },\n changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); },\n\n beforeThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); },\n afterThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); },\n leaveThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); },\n enterThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); },\n\n beforeEvent: function(fsm, name, from, to, args) {\n if ((false === StateMachine.beforeThisEvent(fsm, name, from, to, args)) ||\n (false === StateMachine.beforeAnyEvent( fsm, name, from, to, args)))\n return false;\n },\n\n afterEvent: function(fsm, name, from, to, args) {\n StateMachine.afterThisEvent(fsm, name, from, to, args);\n StateMachine.afterAnyEvent( fsm, name, from, to, args);\n },\n\n leaveState: function(fsm, name, from, to, args) {\n var specific = StateMachine.leaveThisState(fsm, name, from, to, args),\n general = StateMachine.leaveAnyState( fsm, name, from, to, args);\n if ((false === specific) || (false === general))\n return false;\n else if ((StateMachine.ASYNC === specific) || (StateMachine.ASYNC === general))\n return StateMachine.ASYNC;\n },\n\n enterState: function(fsm, name, from, to, args) {\n StateMachine.enterThisState(fsm, name, from, to, args);\n StateMachine.enterAnyState( fsm, name, from, to, args);\n },\n\n //===========================================================================\n\n buildEvent: function(name, map) {\n return function() {\n\n var from = this.current;\n var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from;\n var args = Array.prototype.slice.call(arguments); // turn arguments into pure array\n\n if (this.transition)\n return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, \"event \" + name + \" inappropriate because previous transition did not complete\");\n\n if (this.cannot(name))\n return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, \"event \" + name + \" inappropriate in current state \" + this.current);\n\n if (false === StateMachine.beforeEvent(this, name, from, to, args))\n return StateMachine.Result.CANCELLED;\n\n if (from === to) {\n StateMachine.afterEvent(this, name, from, to, args);\n return StateMachine.Result.NOTRANSITION;\n }\n\n // prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState)\n var fsm = this;\n this.transition = function() {\n fsm.transition = null; // this method should only ever be called once\n fsm.current = to;\n StateMachine.enterState( fsm, name, from, to, args);\n StateMachine.changeState(fsm, name, from, to, args);\n StateMachine.afterEvent( fsm, name, from, to, args);\n return StateMachine.Result.SUCCEEDED;\n };\n this.transition.cancel = function() { // provide a way for caller to cancel async transition if desired (issue #22)\n fsm.transition = null;\n StateMachine.afterEvent(fsm, name, from, to, args);\n }\n\n var leave = StateMachine.leaveState(this, name, from, to, args);\n if (false === leave) {\n this.transition = null;\n return StateMachine.Result.CANCELLED;\n }\n else if (StateMachine.ASYNC === leave) {\n return StateMachine.Result.PENDING;\n }\n else {\n if (this.transition) // need to check in case user manually called transition() but forgot to return StateMachine.ASYNC\n return this.transition();\n }\n\n };\n }\n\n }; // StateMachine\n\n //===========================================================================\n\n //======\n // NODE\n //======\n if (typeof exports !== 'undefined') {\n if (typeof module !== 'undefined' && module.exports) {\n exports = module.exports = StateMachine;\n }\n exports.StateMachine = StateMachine;\n }\n //============\n // AMD/REQUIRE\n //============\n else if (typeof define === 'function' && define.amd) {\n define(function(require) { return StateMachine; });\n }\n //========\n // BROWSER\n //========\n else if (typeof window !== 'undefined') {\n window.StateMachine = StateMachine;\n }\n //===========\n // WEB WORKER\n //===========\n else if (typeof self !== 'undefined') {\n self.StateMachine = StateMachine;\n }\n\n}());\n","import type {AnalyticsConfig} from 'bitmovin-player';\n\nimport type {AdapterAPI} from '../../api/AdapterAPI';\nimport {Analytics} from '../../core/Analytics';\nimport type {CustomDataValues} from '../../types/CustomDataValues';\nimport {guardAgainstDuplicatedUserId, sanitizeAnalyticsConfig} from '../../utils/analyticsConfigUtils';\nimport {areCollectorRequirementsValid} from '../../utils/collectorRequirementChecks';\nimport {VERSION} from '../../utils/Version';\n\nimport {BitmovinPwxInternalAdapter} from './BitmovinPwxInternalAdapter';\nimport type {AnalyticsContext} from './Types';\n\nexport class BitmovinPwxAdapter implements AdapterAPI {\n private readonly internalAdapter: BitmovinPwxInternalAdapter;\n private readonly analytics: Analytics;\n\n constructor(context: AnalyticsContext, config: AnalyticsConfig) {\n // no need to check for player augmentation, if analytics has already been initialized on this player instance,\n // because this adapter is created only once with BitmovinPwxAnalyticsPackage\n\n const sanitizedConfig = sanitizeAnalyticsConfig(config);\n if (!areCollectorRequirementsValid(sanitizedConfig)) {\n throw new Error('Failed to create BitmovinPwxAdapter: domain is required');\n }\n\n guardAgainstDuplicatedUserId(sanitizedConfig);\n\n this.internalAdapter = new BitmovinPwxInternalAdapter(context);\n this.analytics = Analytics.create(sanitizedConfig, this.internalAdapter);\n }\n\n dispose() {\n this.internalAdapter.release();\n }\n\n static readonly version: string = VERSION;\n\n get version(): string {\n return VERSION;\n }\n\n getCurrentImpressionId = () => this.analytics.getCurrentImpressionId();\n\n getUserId = () => this.analytics.getUserId();\n\n setCustomData = (values: CustomDataValues) => this.internalAdapter.setCustomData(values);\n\n setCustomDataOnce = (values: CustomDataValues) => this.analytics.setCustomDataOnce(values);\n\n sourceChange = (_config: AnalyticsConfig) => {\n // Every time a source is added, a new instance of analytics package is triggered. So technically there are\n // no source changes. Also, a single player instance can handle infinite amount of sources at once.\n //\n // We are aware, at the moment we are handling it as \"every source = one session\". We will need to do\n // some additional work in the future (once we figure out how this part should work) to handle multiple\n // sources in one session (e.g. ads).\n //\n // What we mean by \"no source changes\", is that you do not have API to change \"current playing\" source\n // to something else. You would need to add new source and remove old one (or keep it). One instance can\n // have infinite amount of sources, each source for us is a new analytics session (for now, in certain cases\n // they should be tied together - e.g. ads)\n //\n // @see https://github.com/bitmovin-engineering/bitmovin-analytics-collector/pull/867#discussion_r1660699646\n\n throw new Error('Method not implemented.');\n };\n}\n","import type {EmptyObject} from '@bitmovin/player-web-x/framework-types/BaseTypes';\nimport type {AnyPackage} from '@bitmovin/player-web-x/framework-types/package-api/PackageApi';\n\nimport {tryJSONStringify} from '../../utils/Utils';\n\nimport {BitmovinPwxAdapter} from './BitmovinPwxAdapter';\nimport {\n BundleExportNames,\n CoreExportNames,\n PlaybackApiEventsPackageExportNames,\n SourceExportNames,\n SourcesApiExportNames,\n} from './ExportNames';\nimport type {AnalyticsContext, CreatePackage} from './Types';\n\n/**\n * Copy&pasted from `@bitmovin/player-web-x` !\n *\n * We need `createPackage` function from util file to create a PWX package, but because `@bitmovin/player-web-x` is not\n * ES5 compliant, we had to copy it here.\n *\n * @see https://github.com/bitmovin-engineering/player-web-phoenix-framework/blob/main/src/package-api/PackageApiUtils.ts#L9\n */\nconst createPackageFn: CreatePackage = (name, onAdd, dependencies) => {\n (onAdd as any)._name = name;\n\n return {\n onAdd,\n dependencies,\n } as unknown as AnyPackage<EmptyObject>;\n};\n\nexport const BitmovinPwxAnalyticsPackage = createPackageFn(\n 'analytics-package',\n (_, baseContext) => {\n /*\n Player Web X analytics package.\n It is being run for every source added - so there is no actual source switching per analytics instance.\n Package is instantiating the adapter, and making sure it is disposed once package is aborted.\n */\n\n const {EventListenerEffectFactory, StateEffectFactory} = baseContext.registry.get(CoreExportNames.CoreEffects);\n const context = baseContext.using(EventListenerEffectFactory, StateEffectFactory) as unknown as AnalyticsContext;\n const logger = context.registry.get(BundleExportNames.Logger);\n const source = context.registry.get(SourceExportNames.SourceState);\n const playerConfig = context.registry.get(BundleExportNames.PlayerConfig);\n const analyticsConfig = playerConfig.analytics ?? {};\n // if the player key is not set in analytics config, use the one from player config\n analyticsConfig.playerKey = analyticsConfig.playerKey ?? playerConfig.key;\n\n logger.log(`Applying analytics config ${tryJSONStringify(analyticsConfig)}`);\n const adapter = new BitmovinPwxAdapter(context, analyticsConfig);\n\n logger.log(`Analytics package initializing for \"${source.url}\"...`);\n\n const listener = () => {\n context.abortSignal.removeEventListener('abort', listener);\n logger.log(`Analytics package disposing for \"${source.url}\"`);\n adapter.dispose();\n };\n\n context.abortSignal.addEventListener('abort', listener);\n },\n [\n BundleExportNames.Logger,\n BundleExportNames.PlayerConfig,\n CoreExportNames.Constants,\n CoreExportNames.CoreEffects,\n CoreExportNames.CoreStateAtoms,\n SourceExportNames.SourceState,\n SourcesApiExportNames.SourceEventBus,\n PlaybackApiEventsPackageExportNames.PlaybackEvent,\n ],\n) as any; // we cast package as any to prevent DTS bundle type merging\n","import {StateMachine} from 'javascript-state-machine';\n\nimport {AnalyticsStateMachine} from '../../analyticsStateMachines/AnalyticsStateMachine';\nimport {\n customStateMachineErrorCallback,\n getAllStatesBut,\n logMissingCallbackWarning,\n logStateMachineTransition,\n on,\n} from '../../analyticsStateMachines/stateMachineUtils';\nimport type {HeartbeatService} from '../../core/HeartbeatService';\nimport {Event, JSM_INITIAL_EVENT} from '../../enums/Event';\nimport type {AnalyticsStateMachineOptions} from '../../types/AnalyticsStateMachineOptions';\nimport type {StateMachineCallbacks} from '../../types/StateMachineCallbacks';\nimport {EventDebugging} from '../../utils/EventDebugging';\nimport {logger} from '../../utils/Logger';\nimport {isNumber} from '../../utils/numberUtils';\nimport {isFunction} from '../../utils/Utils';\n\nexport enum State {\n END = 'END',\n ERROR = 'ERROR',\n PAUSE = 'PAUSE',\n PLAYING = 'PLAYING',\n READY = 'READY',\n SETUP = 'SETUP',\n SOURCE_LOADED = 'SOURCE_LOADED',\n STARTUP = 'STARTUP',\n VIDEOSTART_FAILED = 'VIDEOSTART_FAILED',\n}\n\nexport class BitmovinPwxAnalyticsStateMachine extends AnalyticsStateMachine {\n private enabledDebugging = false;\n private debuggingStates: EventDebugging[] = [];\n\n constructor(\n stateMachineCallbacks: StateMachineCallbacks,\n playingHeartbeatService: HeartbeatService,\n opts: AnalyticsStateMachineOptions,\n ) {\n super(stateMachineCallbacks, playingHeartbeatService, opts);\n }\n\n override createStateMachine(opts: AnalyticsStateMachineOptions): StateMachine {\n return StateMachine.create({\n // custom initial state and custom JSM initial event name\n // initial event is used by JSM for the initial state transition 'none' -> 'SETUP'\n initial: {state: State.SETUP, event: JSM_INITIAL_EVENT},\n error: customStateMachineErrorCallback,\n events: [\n {\n name: Event.SOURCE_LOADED,\n from: [State.SETUP, State.ERROR],\n to: State.READY,\n },\n on(Event.READY).stayIn(State.READY),\n on(Event.PAUSE).stayIn(State.READY),\n on(Event.TIMECHANGED).stayIn(State.READY),\n {name: Event.PLAY, from: State.READY, to: State.STARTUP},\n {name: Event.PLAYING, from: State.READY, to: State.PLAYING},\n\n on(Event.PLAY).stayIn(State.STARTUP),\n on(Event.PLAYING).stayIn(State.STARTUP),\n {name: Event.TIMECHANGED, from: State.STARTUP, to: State.PLAYING},\n on(Event.READY).stayIn(State.STARTUP),\n {name: Event.PAUSE, from: State.STARTUP, to: State.READY},\n\n on(Event.PLAYING).stayIn(State.PLAYING),\n on(Event.TIMECHANGED).stayIn(State.PLAYING),\n\n {name: Event.PAUSE, from: State.PLAYING, to: State.PAUSE},\n on(Event.TIMECHANGED).stayIn(State.PAUSE),\n on(Event.PAUSE).stayIn(State.PAUSE),\n {name: Event.PLAY, from: State.PAUSE, to: State.PLAYING},\n {name: Event.PLAYING, from: State.PAUSE, to: State.PLAYING},\n\n {name: Event.END, from: State.PLAYING, to: State.END},\n {name: Event.END, from: State.PAUSE, to: State.END},\n // when replay is triggered (play button is clicked once video finished),\n // we should start a new session, so we should go to STARTUP state\n {name: Event.PLAYING, from: State.END, to: State.STARTUP},\n\n on(Event.TIMECHANGED).stayIn(State.END),\n on(Event.END).stayIn(State.END),\n\n {name: Event.PLAY, from: State.END, to: State.STARTUP},\n {name: Event.ERROR, from: State.STARTUP, to: State.VIDEOSTART_FAILED},\n {name: Event.ERROR, from: getAllStatesBut([State.STARTUP], State), to: State.ERROR},\n\n {name: Event.UNLOAD, from: getAllStatesBut([State.STARTUP], State), to: State.END},\n {name: Event.UNLOAD, from: [State.STARTUP], to: State.VIDEOSTART_FAILED},\n ],\n\n // Keep callbacks sorted by order in which they are called by JSM library (and after order, sorted by name)\n //\n // Do not use convenience, shortened callbacks\n // - instead of `onEVENT` use `onafterEVENT`\n // - instead of `onSTATE` use `onenterSTATE`\n //\n // see: https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#callbacks\n callbacks: {\n [`onleave${State.PLAYING}`]: () => {\n this.playingHeartbeatService.stopHeartbeat();\n },\n\n onleavestate: (event, from, to, eventTimestamp, eventData) => {\n logStateMachineTransition('LEAVE', event, from, to);\n\n // Skip this JSM callback for JSM initial event\n // This event is fired when the state machine is constructed,\n // to transition us from 'none' to custom initial 'SETUP' state\n if (event === JSM_INITIAL_EVENT) {\n return;\n }\n\n // Skip this JSM callback when an JSM event without a timestamp is called,\n // because it would cause NPE in analytics code (state duration calculation etc.).\n // This probably has happened because the state machine was not used correctly,\n // aka. JSM event was not called via `callEvent` method as it should be!\n if (!eventTimestamp) {\n return;\n }\n\n this.addStatesToLog(event, from, to, eventTimestamp, eventData);\n const stateDuration = eventTimestamp - this.onEnterStateTimestamp;\n const isStartup = from === State.STARTUP && to === State.PLAYING;\n this.maybeSetOrClearVideoStartTimeouts(from, to);\n\n if (isStartup) {\n this.stateMachineCallbacks.startup(stateDuration, State.STARTUP.toLowerCase());\n }\n\n const lowerCaseFrom = String(from).toLowerCase();\n if (event === Event.UNLOAD) {\n this.stateMachineCallbacks.unload(stateDuration, lowerCaseFrom);\n } else if (from === State.SETUP) {\n // Setting Player Startup Time to fixed value of 1ms.\n // We can not get correct Player Startup Time from PWX player, because it does not have an \"onInitialized\" event\n this.stateMachineCallbacks.setup(1, State.SETUP.toLowerCase());\n } else if (event === Event.PAUSE && from === State.STARTUP && to === State.READY) {\n // fired PAUSE event in STARTUP state indicates we are moving back to READY,\n // so we have to clean setTimeout, and we should not call any stateMachineCallbacks\n this.clearVideoStartTimeout();\n } else if (from !== State.ERROR && !isStartup) {\n // Default \"onleavestate\" state machine callback\n //\n // Every time, when we leave a state, we should try to call \"state\" callback,\n // to be able to make \"a cut\" and send analytics sample (if necessary)\n const defaultStateMachineCallbackFn = this.stateMachineCallbacks[lowerCaseFrom];\n if (isFunction(defaultStateMachineCallbackFn)) {\n // a try-catch block to add more resilience against callback errors\n try {\n defaultStateMachineCallbackFn(stateDuration, lowerCaseFrom, eventData);\n } catch (e) {\n logger.error('Exception occurred in State Machine callback ' + lowerCaseFrom, eventData, e);\n }\n } else {\n // if callback is not defined, log a warning to indicate to the developer that\n // - a new callback function needs to be implemented to relay on this default state machine callback\n // - or if no callback is needed, we should\n // - early return from this JSM callback\n // - or add this state to the ignored list\n logMissingCallbackWarning(from, [State.READY]);\n }\n }\n },\n\n [`onenter${State.PLAYING}`]: () => {\n this.playingHeartbeatService.startHeartbeat();\n },\n\n onenterstate: (event, from, to, eventTimestamp, _eventData) => {\n logStateMachineTransition('ENTER', event, from, to);\n\n this.onEnterStateTimestamp = eventTimestamp ?? Date.now();\n // if customer set custom \"start time\" timestamp in AnalyticsStateMachineOptions of adapter constructor,\n // use it and override `onEnterStateTimestamp` during JSM initialization (transition to initial SETUP state)\n if (isNumber(opts.starttime) && event === JSM_INITIAL_EVENT) {\n this.onEnterStateTimestamp = opts.starttime;\n }\n },\n\n [`onafter${Event.ERROR}`]: (_event, _from, _to, _eventTimestamp, eventData) => {\n this.stateMachineCallbacks.error(eventData);\n },\n },\n });\n }\n\n addStatesToLog(\n event: string | undefined,\n from: string | undefined,\n to: string | undefined,\n timestamp: number,\n eventObject: any,\n ) {\n if (this.enabledDebugging) {\n this.debuggingStates.push(new EventDebugging(event, from, to, timestamp, eventObject));\n }\n }\n\n getStates() {\n return this.debuggingStates;\n }\n\n setEnabledDebugging(enabled: boolean) {\n this.enabledDebugging = enabled;\n }\n\n private maybeSetOrClearVideoStartTimeouts(from: string | undefined, to: string | undefined) {\n if (from === State.READY && to === State.STARTUP) {\n this.setVideoStartTimeout();\n } else if (from === State.STARTUP && to === State.PLAYING) {\n this.clearVideoStartTimeout();\n }\n }\n}\n","import type {Analytics} from '../../core/Analytics';\nimport {HeartbeatService} from '../../core/HeartbeatService';\nimport {Event} from '../../enums/Event';\nimport {Player} from '../../enums/Player';\nimport {StreamTypes} from '../../enums/StreamTypes';\nimport {ErrorDetailBackend} from '../../features/errordetails/ErrorDetailBackend';\nimport {ErrorDetailTracking} from '../../features/errordetails/ErrorDetailTracking';\nimport type {Feature} from '../../features/Feature';\nimport type {FeatureConfig} from '../../features/FeatureConfig';\nimport type {AnalyticsStateMachineOptions} from '../../types/AnalyticsStateMachineOptions';\nimport type {FeatureConfigContainer} from '../../types/FeatureConfigContainer';\nimport {normalizeVideoDuration, PlaybackInfo} from '../../types/PlaybackInfo';\nimport {InternalAdapter} from '../internal/InternalAdapter';\nimport type {InternalAdapterAPI} from '../internal/InternalAdapterAPI';\n\nimport {BitmovinPwxAnalyticsStateMachine} from './BitmovinPwxAnalyticsStateMachine';\nimport {\n CoreExportNames,\n PlaybackApiEventsPackageExportNames,\n SourceExportNames,\n SourcesApiExportNames,\n} from './ExportNames';\nimport {AnalyticsContext} from './Types';\n\nconst PWX_ABORT_ERROR_CODE = 1007;\n\nexport class BitmovinPwxInternalAdapter extends InternalAdapter implements InternalAdapterAPI {\n /** Boolean flag to prevent multiple calls of the {@link Event.UNLOAD} event */\n private onBeforeUnLoadEvent = false;\n\n private readonly context: AnalyticsContext;\n\n constructor(context: AnalyticsContext, opts?: AnalyticsStateMachineOptions) {\n super(opts);\n this.context = context;\n const playingHeartbeatService = new HeartbeatService(() => this.currentTime);\n const stateMachine = new BitmovinPwxAnalyticsStateMachine(\n this.stateMachineCallbacks,\n playingHeartbeatService,\n this.opts,\n );\n playingHeartbeatService.setListener(stateMachine);\n this.stateMachine = stateMachine;\n }\n\n private getSource() {\n return this.context.registry.get(SourceExportNames.SourceState);\n }\n\n protected get currentTime(): number {\n return this.getSource().playback.playhead.position;\n }\n\n getAutoPlay(): boolean {\n return this.getSource().config.playback.autoplay;\n }\n\n getCurrentPlaybackInfo(): PlaybackInfo {\n const hls = this.getSource().sourceConfig.resources.filter((v) => v.url.includes('.m3u8'))[0]?.url;\n const dash = this.getSource().sourceConfig.resources.filter((v) => v.url.includes('.mpd'))[0]?.url;\n\n const videoRect = this.getSource().video.element?.getBoundingClientRect();\n const videoWidth = Math.round(videoRect?.width ?? 1);\n const videoHeight = Math.round(videoRect?.height ?? 1);\n\n let streamFormat: StreamTypes | undefined = undefined;\n if (hls) {\n streamFormat = StreamTypes.hls;\n } else if (dash) {\n streamFormat = StreamTypes.dash;\n }\n\n // height, width, codecs and bitrate are fixed until we have quality api\n return {\n ...this.getCommonPlaybackInfo(),\n droppedFrames: 0,\n isMuted: this.getSource().video.element?.muted,\n isLive: this.getSource().stream.type === 'live',\n videoWindowHeight: videoHeight,\n videoWindowWidth: videoWidth,\n videoDuration: normalizeVideoDuration(this.getSource().video.element?.duration),\n videoPlaybackHeight: videoHeight,\n videoPlaybackWidth: videoWidth,\n m3u8Url: hls,\n mpdUrl: dash,\n streamFormat,\n videoCodec: undefined, // not tracked yet\n audioCodec: undefined, // not tracked yet\n videoBitrate: 0, // not tracked yet\n audioBitrate: 0, // not tracked yet\n };\n }\n\n getPlayerName(): string {\n return Player.BITMOVIN_PWX;\n }\n\n getPlayerTech(): string {\n return 'webx:html5';\n }\n\n getPlayerVersion(): string {\n return this.context.registry.get(CoreExportNames.Constants).Version;\n }\n\n initialize(analytics: Analytics): Array<Feature<FeatureConfigContainer, FeatureConfig>> {\n this.registerEventListeners();\n this.registerUnloadEventListeners();\n\n const errorDetailTracking = new ErrorDetailTracking(\n analytics.errorDetailTrackingSettingsProvider,\n new ErrorDetailBackend(analytics.errorDetailTrackingSettingsProvider.collectorConfig),\n [analytics.errorDetailSubscribable],\n undefined,\n );\n\n return [errorDetailTracking];\n }\n\n private registerUnloadEventListeners() {\n let handleCollectorUnload = () => {\n if (!this.onBeforeUnLoadEvent) {\n this.onBeforeUnLoadEvent = true;\n const currentTime = this.context.registry.get(SourceExportNames.SourceState).playback.playhead.position;\n this.eventCallback(Event.UNLOAD, {currentTime});\n }\n this.release();\n };\n handleCollectorUnload = handleCollectorUnload.bind(true);\n\n this.context.abortSignal.addEventListener('abort', handleCollectorUnload);\n this.windowEventTracker.addEventListener('beforeunload', handleCollectorUnload);\n this.windowEventTracker.addEventListener('unload', handleCollectorUnload);\n }\n\n private registerEventListeners() {\n // The context might not be same so a different source event bus is available\n const sourceEventBus = this.context.registry.get(SourcesApiExportNames.SourceEventBus);\n const playbackAtom = this.context.registry.get(SourceExportNames.SourceState).playback;\n const PlaybackEvent = this.context.registry.get(PlaybackApiEventsPackageExportNames.PlaybackEvent);\n\n sourceEventBus.on(PlaybackEvent.Ready, () => {\n this.eventCallback(Event.SOURCE_LOADED, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.Play, () => {\n this.eventCallback(Event.PLAY, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.Playing, () => {\n this.eventCallback(Event.PLAYING, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.Paused, () => {\n this.eventCallback(Event.PAUSE, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.TimeChanged, () => {\n this.eventCallback(Event.TIMECHANGED, {currentTime: playbackAtom.playhead.position});\n });\n sourceEventBus.on(PlaybackEvent.VideoAttached, () => {\n this.eventCallback(Event.SOURCE_LOADED, {currentTime: playbackAtom.playhead.position});\n });\n\n sourceEventBus.on(PlaybackEvent.Ended, () => {\n this.eventCallback(Event.END, {currentTime: playbackAtom.playhead.position});\n });\n\n const abortListener = () => {\n const abortSignalReason = this.context.abortSignal.reason;\n if (abortSignalReason.name === 'SourceRemovedError' || abortSignalReason.name === 'FrameworkDisposedError') {\n this.eventCallback(Event.SOURCE_UNLOADED, {currentTime: playbackAtom.playhead.position});\n } else {\n this.eventCallback(Event.ERROR, {\n currentTime: playbackAtom.playhead.position,\n code: PWX_ABORT_ERROR_CODE,\n message: abortSignalReason.message,\n data: abortSignalReason,\n originalError: abortSignalReason,\n });\n }\n\n this.context.abortSignal.removeEventListener('abort', abortListener);\n };\n\n this.context.abortSignal.addEventListener('abort', abortListener);\n }\n}\n","/*!\n * This file was created to provide Bitmovin Player Web X \"export names\" as constants,\n * because they are exported as enums in 'd.ts' files, that we can't import as value in this project.\n *\n * Once `@bitmovin/player-web-x` bundle will provide these enums in way we could import them, we could remove/simplify this file.\n */\n\nimport type {BundleExportNames as BundleExportNamesEnum} from '@bitmovin/player-web-x/types/bundles/Types';\nimport type {CoreExportNames as CoreExportNamesEnum} from '@bitmovin/player-web-x/types/packages/core/Types';\nimport type {PlaybackApiEventsPackageExportNames as PlaybackApiEventsPackageExportNamesEnum} from '@bitmovin/player-web-x/types/packages/playback-api/playback-api-events/Types';\nimport type {SourceExportNames as SourceExportNamesEnum} from '@bitmovin/player-web-x/types/packages/source/Types';\nimport type {SourcesApiExportNames as SourcesApiExportNameEnum} from '@bitmovin/player-web-x/types/packages/sources-api/Types';\n\nimport type {EnumAsUnion} from '../../utils/EnumAsUnion';\n\nconst BundleExportNamesLogger: EnumAsUnion<typeof BundleExportNamesEnum> = 'logger';\nconst BundleExportNamesPlayerConfig: EnumAsUnion<typeof BundleExportNamesEnum> = 'player-config';\nexport const BundleExportNames = {\n Logger: BundleExportNamesLogger,\n PlayerConfig: BundleExportNamesPlayerConfig,\n};\n\nconst CoreExportNamesUtils: EnumAsUnion<typeof CoreExportNamesEnum> = 'utils';\nconst CoreExportNamesConstants: EnumAsUnion<typeof CoreExportNamesEnum> = 'constants';\nconst CoreExportNamesCoreEffects: EnumAsUnion<typeof CoreExportNamesEnum> = 'core-effects';\nconst CoreExportNamesCoreStateAtoms: EnumAsUnion<typeof CoreExportNamesEnum> = 'core-state-atoms';\nexport const CoreExportNames = {\n Utils: CoreExportNamesUtils,\n Constants: CoreExportNamesConstants,\n CoreEffects: CoreExportNamesCoreEffects,\n CoreStateAtoms: CoreExportNamesCoreStateAtoms,\n} as const;\n\nconst PlaybackApiEventsPackageExportNamesPlaybackEvent: EnumAsUnion<typeof PlaybackApiEventsPackageExportNamesEnum> =\n 'playback-event';\nexport const PlaybackApiEventsPackageExportNames = {\n PlaybackEvent: PlaybackApiEventsPackageExportNamesPlaybackEvent,\n} as const;\n\nconst SourceExportNamesCreateSourceStateAtom: EnumAsUnion<typeof SourceExportNamesEnum> = 'create-source-state-atom';\nconst SourceExportNamesCreateSourceReference: EnumAsUnion<typeof SourceExportNamesEnum> = 'create-source-reference';\nconst SourceExportNamesSourceReferences: EnumAsUnion<typeof SourceExportNamesEnum> = 'source-references';\nconst SourceExportNamesSourceState: EnumAsUnion<typeof SourceExportNamesEnum> = 'source-state-atom';\nexport const SourceExportNames = {\n CreateSourceStateAtom: SourceExportNamesCreateSourceStateAtom,\n CreateSourceReference: SourceExportNamesCreateSourceReference,\n SourceReferences: SourceExportNamesSourceReferences,\n SourceState: SourceExportNamesSourceState,\n} as const;\n\nconst SourcesApiExportNamesSourceApiManager: EnumAsUnion<typeof SourcesApiExportNameEnum> = 'source-api-manager';\nconst SourcesApiExportNamesVideoElementUtils: EnumAsUnion<typeof SourcesApiExportNameEnum> = 'video-element-utils';\nconst SourcesApiExportNamesSourceEventBus: EnumAsUnion<typeof SourcesApiExportNameEnum> = 'source-event-bus';\nexport const SourcesApiExportNames = {\n SourceApiManager: SourcesApiExportNamesSourceApiManager,\n VideoElementUtils: SourcesApiExportNamesVideoElementUtils,\n SourceEventBus: SourcesApiExportNamesSourceEventBus,\n} as const;\n","import {AnalyticsStateMachine} from '../../analyticsStateMachines/AnalyticsStateMachine';\nimport {EventDispatcher} from '../../core/EventDispatcher';\nimport QualityChangeService from '../../core/QualityChangeService';\nimport {SourceInfoFallbackService} from '../../core/SourceInfoFallbackService';\nimport {SsaiService} from '../../core/ssai/SsaiService';\nimport {Event, EventMap} from '../../enums/Event';\nimport {AnalyticsConfig} from '../../types/AnalyticsConfig';\nimport {AnalyticsStateMachineOptions} from '../../types/AnalyticsStateMachineOptions';\nimport {CustomDataValues} from '../../types/CustomDataValues';\nimport {DownloadSpeedInfo} from '../../types/DownloadSpeedInfo';\nimport {DrmPerformanceInfo} from '../../types/DrmPerformanceInfo';\nimport type {CustomDataValuesEvent} from '../../types/EventData';\nimport {NoExtraProperties} from '../../types/NoExtraProperties';\nimport {SegmentInfo} from '../../types/SegmentInfo';\nimport type {SourceMetadata} from '../../types/SourceMetadata';\nimport {defaultStateMachineCallbacks, StateMachineCallbacks} from '../../types/StateMachineCallbacks';\nimport {getGlobalScreenDimensions} from '../../utils/globalScopeUtils';\nimport {logger} from '../../utils/Logger';\nimport {getCurrentTimestamp} from '../../utils/Utils';\nimport {WindowEventTracker} from '../../utils/WindowEventTracker';\n\nimport {EventCallbackDispatcher} from './EventCallbackDispatcher';\n\nexport abstract class InternalAdapter implements EventCallbackDispatcher {\n readonly onLicenseKeyReceived: EventDispatcher<{licenseKey: string}> = new EventDispatcher();\n readonly onLicenseCallFailed: EventDispatcher<any> = new EventDispatcher();\n readonly qualityChangeService: QualityChangeService = new QualityChangeService();\n readonly ssaiService = new SsaiService();\n readonly stateMachineCallbacks: StateMachineCallbacks = {...defaultStateMachineCallbacks};\n\n protected stateMachine!: AnalyticsStateMachine;\n protected opts: AnalyticsStateMachineOptions;\n protected sourceInfoFallbackService: SourceInfoFallbackService = new SourceInfoFallbackService();\n protected drmPerformanceInfo: DrmPerformanceInfo | undefined = undefined;\n protected readonly windowEventTracker: WindowEventTracker = new WindowEventTracker();\n\n protected abstract get currentTime(): number;\n\n constructor(opts?: AnalyticsStateMachineOptions) {\n if (!opts) {\n opts = {\n starttime: undefined,\n };\n }\n if (!opts.starttime) {\n opts.starttime = getCurrentTimestamp();\n }\n\n this.opts = opts;\n }\n\n release() {\n this.stateMachine.resetIntervals();\n this.stateMachineCallbacks.release();\n this.resetSourceRelatedState();\n this.windowEventTracker.release();\n }\n\n eventCallback<StateMachineEvent extends keyof EventMap, StateMachineEventData extends EventMap[StateMachineEvent]>(\n event: StateMachineEvent,\n eventData: NoExtraProperties<EventMap[StateMachineEvent], StateMachineEventData>,\n eventTimestamp: number = Date.now(),\n ) {\n eventData = eventData || {};\n if (!this.stateMachine) {\n logger.log(\"Bitmovin Analytics: StateMachine isn't ready yet\");\n } else {\n this.stateMachine.callEvent(event, eventData, eventTimestamp);\n }\n }\n\n getCommonPlaybackInfo() {\n const dimensions = getGlobalScreenDimensions();\n\n return {\n screenHeight: dimensions?.height,\n screenWidth: dimensions?.width,\n };\n }\n\n getDrmPerformanceInfo(): DrmPerformanceInfo | undefined {\n return undefined;\n }\n\n getSegmentInfo(): SegmentInfo[] {\n return [];\n }\n\n getDownloadSpeedInfo(): DownloadSpeedInfo {\n return {\n segmentsDownloadCount: 0,\n segmentsDownloadSize: 0,\n segmentsDownloadTime: 0,\n avgDownloadSpeed: 0,\n minDownloadSpeed: 0,\n maxDownloadSpeed: 0,\n avgTimeToFirstByte: 0,\n };\n }\n\n resetDownloadSpeedInfoMeasures(): void {\n // noop by default\n }\n\n setCustomData(values: CustomDataValues) {\n const previousState = this.stateMachine.currentState;\n const eventData: CustomDataValuesEvent = {customDataValues: values, currentTime: this.currentTime};\n\n if (\n this.stateMachine.currentState &&\n (this.stateMachine.currentState === 'PAUSE' || this.stateMachine.currentState === 'PLAYING')\n ) {\n // If we are in State.PAUSE or State.PLAYING, we want to make \"a cut\" of the current state\n // to trigger sample sending with current custom data values.\n this.eventCallback(Event.CUSTOM_DATA_CHANGE, {currentTime: this.currentTime});\n // Then we have to call this \"previous state\" event to return back\n // to the previous state and to set new custom data values.\n // !! here we relay on the fact that we have `PAUSE` and `PLAYING` events with the same name as the states above !!\n this.eventCallback(Event[previousState], eventData);\n }\n // ... else, for any other states, we don't care, and we will just set new custom data values asap, so they will\n // be sent with the upcoming sample\n else {\n this.stateMachineCallbacks.customdatachange(undefined, undefined, eventData);\n }\n }\n\n sourceChange(analyticsConfig: AnalyticsConfig): void {\n this.eventCallback(Event.MANUAL_SOURCE_CHANGE, {currentTime: this.currentTime, config: analyticsConfig});\n }\n\n resetSourceRelatedState(): void {\n this.sourceInfoFallbackService.reset();\n this.drmPerformanceInfo = undefined;\n }\n\n programChange(sourceMetadata: SourceMetadata): void {\n const isSsaiActive = this.ssaiService.isInActiveState();\n this.stateMachine.programChange(this.currentTime, isSsaiActive, sourceMetadata);\n }\n}\n","import {AdBreakInfo} from '../../../types/ads/AdBreakInfo';\nimport {AdInfo} from '../../../types/ads/AdInfo';\n\nexport class AdCallbacks {\n onAdStarted = (_ad: AdInfo): void => undefined;\n onAdFinished = (_ad: AdInfo): void => undefined;\n onAdBreakStarted = (_adBreak: AdBreakInfo): void => undefined;\n onAdBreakFinished = (_adBreak: AdBreakInfo): void => undefined;\n onAdClicked = (_event: AdClickedPayload): void => undefined;\n onAdError = (_event: AdErrorPayload): void => undefined;\n onAdManifestLoaded = (_event: AdManifestLoadedPayload): void => undefined;\n onAdQuartile = (_event: AdQuartilePayload): void => undefined;\n onAdSkipped = (_ad: AdInfo): void => undefined;\n onPlay = (): void => undefined;\n onPause = (): void => undefined;\n onBeforeUnload = (): void => undefined;\n}\n\nexport interface AdModuleAPI {\n readonly adCallbacks: AdCallbacks;\n isLinearAdActive: () => boolean;\n getContainer: () => HTMLElement | undefined;\n getAdModuleInfo: () => {name?: string; version?: string};\n currentTime: () => number;\n getAutoPlay(): boolean;\n}\n\nexport interface AdClickedPayload {\n clickThroughUrl?: string;\n}\n\nexport interface AdErrorPayload {\n code?: number;\n message?: string;\n adBreakInfo?: AdBreakInfo;\n activeAdId?: string;\n}\n\nexport interface AdManifestLoadedPayload {\n adBreakInfo?: AdBreakInfo;\n manifestDownloadTime?: number;\n isVmap: boolean;\n}\n\nexport enum AdQuartile {\n FIRST_QUARTILE = 'firstQuartile',\n MIDPOINT = 'midpoint',\n THIRD_QUARTILE = 'thirdQuartile',\n}\n\nexport interface AdQuartilePayload {\n quartile: AdQuartile;\n}\n","import type {HeartbeatListener} from '../core/HeartbeatService';\nimport {HeartbeatService} from '../core/HeartbeatService';\nimport {SSAI_RELATED_SAMPLE_MARKER} from '../core/ssai/ssaiUtils';\nimport {ErrorCode} from '../enums/ErrorCode';\nimport {Event, EventMap} from '../enums/Event';\nimport type {AnalyticsStateMachineOptions} from '../types/AnalyticsStateMachineOptions';\nimport type {NoExtraProperties} from '../types/NoExtraProperties';\nimport type {SourceMetadata} from '../types/SourceMetadata';\nimport {HeartbeatPayload, StateMachineCallbacks} from '../types/StateMachineCallbacks';\nimport {logger} from '../utils/Logger';\nimport * as Settings from '../utils/Settings';\nimport * as Utils from '../utils/Utils';\nimport {isNotNullish} from '../utils/Utils';\n\nconst BUFFERING_HEARTBEAT_INTERVALS = [3000, 5000, 10000, 30000, 59700];\n\nexport abstract class AnalyticsStateMachine implements HeartbeatListener {\n protected stateMachine: StateMachine.StateMachine & {[key: string]: any};\n protected onEnterStateTimestamp = 0;\n\n protected readonly videoStartupTimeoutMs: number = Settings.ANALYTICS_VIDEOSTART_TIMEOUT;\n protected readonly bufferTimeoutMs: number = Settings.ANALYTICS_BUFFER_TIMEOUT;\n protected readonly playingHeartbeatService: HeartbeatService;\n\n private bufferingHeartbeatIntervalHandle?: ReturnType<typeof setInterval>;\n private currentBufferingIntervalIndex = 0;\n private bufferingTimeoutHandle?: ReturnType<typeof setTimeout>;\n private videoStartTimeout?: ReturnType<typeof setTimeout>;\n\n constructor(\n protected stateMachineCallbacks: StateMachineCallbacks,\n playingHeartbeatService: HeartbeatService,\n opts: AnalyticsStateMachineOptions,\n ) {\n this.stateMachine = this.createStateMachine(opts);\n this.playingHeartbeatService = playingHeartbeatService;\n }\n\n abstract createStateMachine(opts: AnalyticsStateMachineOptions): StateMachine.StateMachine;\n\n callEvent<StateMachineEvent extends keyof EventMap, StateMachineEventData extends EventMap[StateMachineEvent]>(\n event: StateMachineEvent,\n eventData: NoExtraProperties<EventMap[StateMachineEvent], StateMachineEventData>,\n eventTimestamp: number,\n ): void {\n const stateMachineEventMethod = this.stateMachine[event];\n\n if (stateMachineEventMethod == null) {\n // If the event (aka. the event method) is not defined in the JSM, we log a warning,\n // because it means that we are explicitly trying to call that JSM event from our code (probably adapter),\n // but it was not defined in the JSM at all. Either we are missing it or it should not be called at all!\n logger.warn(`StateMachine ignored event \"${event}\" call, because it was not defined`, eventData, eventTimestamp);\n return;\n }\n\n try {\n // By default, if you try to call an event method not allowed in the current state, the state machine will throw an exception.\n // see: https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#handling-failures\n //\n // This JSM library behavior can be changed by providing \"a custom error handler\" in the `create()`\n // method of the state machine, and we do that in every state machine!\n //\n // But we still want to have here a try-catch block, in case of unexpected state machine code,\n // to avoid propagating the exception to the rest of the application (and breaking customer app).\n stateMachineEventMethod.call(this.stateMachine, eventTimestamp, eventData);\n } catch (e) {\n logger.error(\n `StateMachine ignored event \"${event}\" call, because it has thrown exception in the current state \"${this.currentState}\"`,\n eventData,\n eventTimestamp,\n e,\n );\n }\n }\n\n get currentState(): string {\n return this.stateMachine.current;\n }\n\n resetIntervals() {\n this.clearVideoStartTimeout();\n this.clearBufferingTimeoutHandle(true);\n this.clearBufferingHeartbeatHandle();\n }\n\n //#region buffer timeout\n\n protected startBufferingHeartbeatInterval(reset = true) {\n this.resetBufferingHelpers(reset);\n\n this.startBufferingTimeoutHandle();\n\n this.bufferingHeartbeatIntervalHandle = setInterval(() => {\n const state = this.stateMachine.current.toLowerCase();\n if (state !== 'buffering') {\n this.resetBufferingHelpers();\n return;\n }\n const timestamp = new Date().getTime();\n const stateDuration = timestamp - this.onEnterStateTimestamp;\n this.stateMachineCallbacks.heartbeat(stateDuration, state, {buffered: stateDuration});\n this.onEnterStateTimestamp = timestamp;\n this.currentBufferingIntervalIndex = Math.min(\n this.currentBufferingIntervalIndex + 1,\n BUFFERING_HEARTBEAT_INTERVALS.length - 1,\n );\n this.startBufferingHeartbeatInterval(false);\n }, BUFFERING_HEARTBEAT_INTERVALS[this.currentBufferingIntervalIndex]);\n }\n\n protected resetBufferingHelpers(reset = true) {\n if (reset) {\n this.currentBufferingIntervalIndex = 0;\n }\n this.clearBufferingHeartbeatHandle();\n this.clearBufferingTimeoutHandle(reset);\n }\n\n protected clearBufferingHeartbeatHandle() {\n if (isNotNullish(this.bufferingHeartbeatIntervalHandle)) {\n clearInterval(this.bufferingHeartbeatIntervalHandle);\n this.bufferingHeartbeatIntervalHandle = undefined;\n }\n }\n\n private startBufferingTimeoutHandle() {\n if (this.currentBufferingIntervalIndex > 0) {\n return;\n }\n this.bufferingTimeoutHandle = setTimeout(() => {\n this.callEvent(\n Event.ERROR,\n {\n ...ErrorCode.BUFFERING_TIMEOUT_REACHED,\n data: {\n additionalData: `StateMachine timed out after ${this.bufferTimeoutMs} ms of consecutive buffering.`,\n },\n },\n Utils.getCurrentTimestamp(),\n );\n this.stateMachineCallbacks.release();\n }, this.bufferTimeoutMs);\n }\n\n protected clearBufferingTimeoutHandle(reset: boolean) {\n if (reset && isNotNullish(this.bufferingTimeoutHandle)) {\n clearTimeout(this.bufferingTimeoutHandle);\n this.bufferingTimeoutHandle = undefined;\n }\n }\n //#endregion\n\n //#region videoStartupFailed\n protected setVideoStartTimeout() {\n if (isNotNullish(this.videoStartTimeout)) {\n this.clearVideoStartTimeout();\n }\n this.videoStartTimeout = setTimeout(() => {\n this.callEvent(Event.VIDEOSTART_TIMEOUT, {}, Date.now());\n this.stateMachineCallbacks.release();\n }, this.videoStartupTimeoutMs);\n }\n\n protected clearVideoStartTimeout() {\n clearTimeout(this.videoStartTimeout);\n this.videoStartTimeout = undefined;\n }\n //#endregion\n\n onHeartbeat(playerCurrentTime: number): void {\n this.sendPlayingSample(Date.now(), playerCurrentTime);\n }\n\n /**\n * Should be used in the \"PLAYING\" state only, and only by \"SSAI\", \"ProgramChange\" and \"Playing Heartbeat\" features,\n * otherwise it will log a warning and do nothing!\n *\n * It calls the {@link StateMachineCallbacks.heartbeat} callback, to send out the current playing sample (it cuts\n * current PLAYING state) and resets time measurements to set a new start of PLAYING state again with new timestamp\n * and video time. So the next sample will be sent with the duration from the last cut.\n *\n * We have chosen to use {@link StateMachineCallbacks.heartbeat} callback here, because it was the easiest and the\n * fastest way to trigger 'playing' sample sending (with additional properties like \"ssai marker\"), without changing\n * and refactoring too much code, in future this code should be refactored with better naming.\n *\n * @param timestamp current timestamp\n * @param playerCurrentTime the current player playback time of the video in seconds\n * @param triggeredBySsai boolean to mark the sample as SSAI triggered\n * @param triggeredByProgramChange boolean to mark the sample as ProgramChange triggered\n */\n sendPlayingSample(\n timestamp: number,\n playerCurrentTime: number,\n triggeredBySsai = false,\n triggeredByProgramChange = false,\n ) {\n const state = this.stateMachine.current.toLowerCase();\n // We don't allow this in any other state because it could interrupt the natural flow of the states.\n // Only PLAYING is considered a state which we can interrupt/cut by heartbeat or SSAI interaction.\n if (state !== 'playing') {\n // our logic for \"SSAI\" and \"playing heartbeat\" is built on the assumption that we send only 'playing' samples,\n // but that \"if\" restriction is spread across the codebase, so we need to log a warning here, to see a potential\n // problems in our logic, if reported by from customer and report will contain these logs\n logger.warn(`Unexpected call of \"sendPlayingSample\" in AnalyticsStateMachine from \"${state}\" state`);\n return;\n }\n\n this.stateMachineCallbacks.setVideoTimeEndFromEvent({currentTime: playerCurrentTime});\n\n const stateDuration = timestamp - this.onEnterStateTimestamp;\n const payload: HeartbeatPayload = {\n played: stateDuration,\n isProgramChange: triggeredByProgramChange ? true : undefined,\n };\n\n if (triggeredBySsai) {\n payload[SSAI_RELATED_SAMPLE_MARKER] = true;\n }\n\n this.stateMachineCallbacks.heartbeat(stateDuration, state, payload);\n\n this.resetCurrentStateStart(timestamp, playerCurrentTime);\n }\n\n private resetCurrentStateStart(stateEnterTimestamp: number, playerCurrentTime: number): void {\n this.onEnterStateTimestamp = stateEnterTimestamp;\n this.stateMachineCallbacks.setVideoTimeStartFromEvent({currentTime: playerCurrentTime});\n }\n\n programChange(playerCurrentTime: number, isSsaiActive: boolean, sourceMetadata: SourceMetadata): void {\n // if program change happens before or during STARTUP (or other \"startup state\", like bitmovin8 STARTUP_AUTOPLAY),\n // we don't want to do any \"cut\", because it has not started yet, we just want to update source metadata\n // and wait for the natural start\n if (\n this.stateMachine.current === 'SETUP' ||\n this.stateMachine.current === 'READY' ||\n this.stateMachine.current === 'STARTUP' ||\n this.stateMachine.current === 'STARTUP_AUTOPLAY'\n ) {\n this.stateMachineCallbacks.updateSourceMetadata(sourceMetadata);\n return;\n }\n\n const programChangeTimestamp = Date.now();\n\n // If the program change happens during PLAYING state, we want to \"cut it\" and send asap last playing sample\n // of the previous program (session) with the duration from the start of PLAYING state to the program change\n if (this.stateMachine.current === 'PLAYING') {\n this.sendPlayingSample(programChangeTimestamp, playerCurrentTime, isSsaiActive, true);\n }\n // ... else in any other state, we just want to reset time measurements to set a new start of the current state\n else {\n this.resetCurrentStateStart(programChangeTimestamp, playerCurrentTime);\n }\n\n this.stateMachineCallbacks.programChange(sourceMetadata);\n }\n}\n","import {\n StateMachineErrorCallback,\n Error as StateMachineErrorCode,\n StateMachineEventDef,\n} from 'javascript-state-machine';\n\nimport {logger, padRight} from '../utils/Logger';\nimport {objectValues} from '../utils/objectUtils';\nimport {isNullish, tryJSONStringify} from '../utils/Utils';\n\n/**\n * @deprecated use {@link whileIn} instead, to switch mindset and think about allowed events in the current state\n * instead of thinking of current event and its allowed states. Because as analytics we focus mostly on reporting\n * states or states changes.\n */\nexport const on = (event: string): {stayIn: (state: string) => StateMachineEventDef} => ({\n stayIn: (state: string) => ({name: event, from: state, to: state}),\n});\n\ntype EventsToStateMachineEventDefFn = (...events: string[]) => StateMachineEventDef[];\ntype WhileInReturnType = {\n /**\n * Create {@link StateMachineEventDef} from event(s) to be used in the state machine definition, but ONLY to indicate\n * that we want to only pass event(s) over, to avoid a log message of ignored event in the current state from\n * the state machine.\n *\n * @remarks\n *\n * If we decide in the future to ignore {@link StateMachineErrorCode.INVALID_TRANSITION} logs created in\n * {@link customStateMachineErrorCallback}, this method and JSM event definitions created with could be removed\n * from source code. Until then, we use it to make code more readable.\n */\n passOver: EventsToStateMachineEventDefFn;\n\n /**\n * Same as {@link passOver}, but used in rare cases, when it indicates that we expect the event(s) to occur\n * in the current state, aka. we want to trigger the state machine event callbacks for these event(s),\n * even if we stay in the same state.\n *\n * @remarks\n *\n * If we don't expect the event while staying in the current state, we don't expect state machine event callbacks\n * to run, we should use {@link passOver} instead!\n */\n runEventCallbacksFor: EventsToStateMachineEventDefFn;\n};\n\n/**\n * This utility is here to help us write more readable code and let us define allowed/expected events in the current state.\n *\n * ### Example:\n *\n * Instead of writing:\n *\n * ```typescript\n * {name: Event.PAUSE, from: State.END, to: State.END},\n * {name: Event.SEEK, from: State.END, to: State.END},\n * {name: Event.SEEKED, from: State.END, to: State.END},\n * {name: Event.TIMECHANGED, from: State.END, to: State.END},\n * ```\n *\n * we can write:\n *\n * ```typescript\n * ...whileIn(State.END).passOver(Event.PAUSE, Event.SEEK, Event.SEEKED, Event.TIMECHANGED),\n * // OR when we expect and react on that event occurrence:\n * ...whileIn(State.END).runEventCallbacksFor(Event.PAUSE, Event.SEEK, Event.SEEKED, Event.TIMECHANGED),\n * ```\n *\n * @see customStateMachineErrorCallback\n * @see https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#handling-failures\n */\nexport const whileIn = (state: string): WhileInReturnType => {\n const stateMachineEventDefBuilderFn = (...events: string[]) =>\n events.map((event) => ({name: event, from: state, to: state}));\n return {runEventCallbacksFor: stateMachineEventDefBuilderFn, passOver: stateMachineEventDefBuilderFn};\n};\n\n/**\n * By default, if you try to call an event method not allowed in the current state,\n * the state machine will throw an exception (not allow it).\n *\n * This JSM library behavior can be changed by providing \"a custom error handler\" in the `create()`\n * method of the state machine, and we do that in every state machine!\n *\n * This way we make code more resilient to errors, because we do not throw errors from JSM event methods,\n * but instead we handle them here and just log them with {@link logger}.\n *\n * @see https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#handling-failures\n */\nexport const customStateMachineErrorCallback: StateMachineErrorCallback = (\n eventName,\n from,\n to,\n args,\n errorCode,\n errorMessage,\n _ex,\n) => {\n const loggerMessage = `StateMachine ignored event \"${eventName}\", ${errorMessage}`;\n const loggerMessageData = {\n eventName,\n from,\n to,\n args: tryJSONStringify(args),\n errorCode,\n errorMessage,\n };\n\n // if caller tried to fire an event that was inappropriate in the current state\n if (errorCode === StateMachineErrorCode.INVALID_TRANSITION) {\n // The event itself is defined in JSM (in some other StateMachineEventDef). However, it is just not considered to\n // be appropriate in the current state.\n //\n // We should log it as a simple log. It is not an error nor a warning,\n // - because JSM will just stay in the same JSM state (and that can be considered as expected behavior)\n // - BUT it will NOT trigger JSM event callbacks like `onafterEVENT`, on `onbeforeEVENT`!\n logger.log(loggerMessage, loggerMessageData);\n return;\n }\n\n logger.error(loggerMessage, loggerMessageData);\n};\n\n/**\n * Log warning messages with {@link logger} about missing StateMachine callback,\n * if the state is not nullish and does not match any of the ignored states.\n */\nexport const logMissingCallbackWarning = (state: string | undefined, ignoreStates: string[] = []) => {\n if (isNullish(state)) {\n return;\n }\n\n const shouldReportMissingCallback = isNullish(ignoreStates.find((ignoredState) => state === ignoredState));\n if (shouldReportMissingCallback) {\n logger.warn('Could not find StateMachine callback function for ' + state);\n }\n};\n\n/** Log message with {@link logger} about StateMachine ENTER/LEAVE transition */\nexport const logStateMachineTransition = (\n transition: 'ENTER' | 'LEAVE',\n event: string | undefined,\n from: string | undefined,\n to: string | undefined,\n) => {\n if (transition === 'ENTER') {\n logger.log(`[ENTER] ${padRight(to, 20)} EVENT: ${padRight(event, 20)} from ${padRight(from, 20)}`);\n } else {\n logger.log(`[LEAVE] ${padRight(from, 20)} EVENT: ${padRight(event, 20)} to ${padRight(to, 20)}`);\n }\n};\n\n/**\n * Return all values/states of the given state string enum.\n *\n * @param stateStringEnumObj\n *\n * @remarks\n *\n * We cannot directly check at if an object is a TypeScript string enum, because enums are erased at compile time and\n * become plain objects in JavaScript. However, you can heuristically check if an object looks like a string enum\n * by verifying that all its values are strings. This checks if all values of the object are strings, which is typical\n * for a string enum. However, this is not a foolproof check, just a heuristic.\n */\nexport function getAllStates<T extends {[key: string]: string}>(stateStringEnumObj: T): Array<T[keyof T]> {\n return objectValues(stateStringEnumObj) as Array<T[keyof T]>;\n}\n\nexport function getAllStatesBut<T extends {[key: string]: string}>(\n excludedStates: Array<T[keyof T]>,\n stateEnumObj: T,\n): Array<T[keyof T]> {\n return getAllStates(stateEnumObj).filter((s) => excludedStates.indexOf(s) < 0);\n}\n","import {\n AdClickedPayload,\n AdErrorPayload,\n AdManifestLoadedPayload,\n AdModuleAPI,\n AdQuartile,\n AdQuartilePayload,\n} from '../adapters/internal/ads/AdModuleAPI';\nimport {AdBreakInfo} from '../types/ads/AdBreakInfo';\nimport {AdInfo} from '../types/ads/AdInfo';\nimport type {AdSample} from '../types/AdSample';\nimport {logger} from '../utils/Logger';\nimport {isFiniteNumber} from '../utils/numberUtils';\nimport {buildAdSample} from '../utils/sampleUtils';\nimport * as Utils from '../utils/Utils';\nimport {isNotNullish, isNullish, tryJSONStringify} from '../utils/Utils';\nimport {generateUUID} from '../utils/uuidUtils';\nimport {VERSION} from '../utils/Version';\nimport {ViewportTracker} from '../utils/ViewportTracker';\n\nimport {Analytics} from './Analytics';\n\nexport class AdAnalytics {\n static readonly MODULE_NAME = 'ads';\n private static readonly TIMEOUT_CURRENT_TIME_INTERVAL = 100;\n\n /** Boolean flag to prevent multiple calls of the {@link Event.UNLOAD} event */\n private onBeforeUnLoadEvent = false;\n private analytics: Analytics;\n private adapter: AdModuleAPI;\n private viewportTracker?: ViewportTracker;\n\n private activeAdBreakState: ActiveAdBreakState | undefined;\n private activeAdState: ActiveAdState | undefined;\n\n private adManifestDownloadTime: number | undefined;\n private adStartupTimestamp?: number;\n private beginPlayingTimestamp?: number;\n private enterViewportTimestamp?: number;\n private isPlaying = false;\n private currentTime?: number;\n private currentTimeInterval?: ReturnType<typeof setInterval>;\n private adPodPosition = 0;\n\n constructor(analytics: Analytics, adapter: AdModuleAPI) {\n this.analytics = analytics;\n this.adapter = adapter;\n\n this.adapter.adCallbacks.onAdStarted = (event) => this.onAdStarted(event);\n this.adapter.adCallbacks.onAdFinished = (event) => this.onAdFinished(event);\n this.adapter.adCallbacks.onAdBreakStarted = (event) => this.onAdBreakStarted(event);\n this.adapter.adCallbacks.onAdBreakFinished = (event) => this.onAdBreakFinished(event);\n this.adapter.adCallbacks.onAdClicked = (event) => this.onAdClicked(event);\n this.adapter.adCallbacks.onAdError = (event) => this.onAdError(event);\n this.adapter.adCallbacks.onAdManifestLoaded = (event) => this.onAdManifestLoaded(event);\n this.adapter.adCallbacks.onPlay = () => this.onPlay();\n this.adapter.adCallbacks.onPause = () => this.onPause();\n this.adapter.adCallbacks.onBeforeUnload = () => this.onBeforeUnload();\n this.adapter.adCallbacks.onAdSkipped = (event) => this.onAdSkipped(event);\n this.adapter.adCallbacks.onAdQuartile = (event) => this.onAdQuartile(event);\n\n const container = this.adapter.getContainer();\n if (isNotNullish(container)) {\n this.viewportTracker = new ViewportTracker(container, () => this.onIntersectionChanged(), 0.5);\n }\n }\n\n release() {\n this.clearCurrentTimeInterval();\n this.viewportTracker?.dispose();\n this.adManifestDownloadTime = undefined;\n }\n\n onIntersectionChanged() {\n if (!this.activeAdState) {\n return;\n }\n if (this.isContainerInViewport()) {\n this.enterViewportTimestamp = Date.now();\n } else {\n if (this.enterViewportTimestamp) {\n this.activeAdState.timeInViewport =\n (this.activeAdState.timeInViewport || 0) + Date.now() - this.enterViewportTimestamp;\n }\n }\n }\n\n isContainerInViewport(): boolean {\n return this.viewportTracker ? this.viewportTracker.isInViewport() : true;\n }\n\n onPlay() {\n if (this.adapter && this.adapter.isLinearAdActive() && this.activeAdState) {\n const timestamp = Date.now();\n this.beginPlayingTimestamp = timestamp;\n this.enterViewportTimestamp = timestamp;\n this.isPlaying = true;\n }\n }\n\n onPause() {\n if (this.adapter && this.adapter.isLinearAdActive() && this.activeAdState) {\n this.updatePlayingTime(this.activeAdState);\n this.isPlaying = false;\n }\n }\n\n onAdManifestLoaded(payload: AdManifestLoadedPayload) {\n if (payload.isVmap) {\n this.sendAnalyticsRequest(buildInitialActiveAdBreakState(payload.adBreakInfo));\n return;\n }\n\n this.adManifestDownloadTime = payload.manifestDownloadTime;\n }\n\n onAdBreakStarted(adBreak: AdBreakInfo) {\n this.adPodPosition = 0;\n this.activeAdBreakState = buildInitialActiveAdBreakState({\n ...adBreak,\n manifestDownloadTime: this.adManifestDownloadTime,\n });\n delete this.adManifestDownloadTime;\n this.adStartupTimestamp = Date.now();\n }\n\n onAdBreakFinished(_adBreak: AdBreakInfo) {\n this.resetActiveAd();\n this.activeAdBreakState = undefined;\n }\n\n onAdStarted(adInfo: AdInfo) {\n if (!adInfo.isLinear) {\n return;\n }\n\n this.resetActiveAd();\n this.activeAdState = buildInitialActiveAdState(adInfo);\n this.currentTime = undefined;\n this.activeAdState.adStartupTime = this.adStartupTimestamp ? Date.now() - this.adStartupTimestamp : undefined;\n\n this.startAd(this.activeAdState);\n }\n\n onAdFinished(_ad: AdInfo) {\n if (!this.activeAdBreakState || !this.activeAdState) {\n return;\n }\n\n const activeAdStateCopy = {...this.activeAdState};\n activeAdStateCopy.completed = 1;\n this.resetActiveAd();\n this.completeAd(this.activeAdBreakState, activeAdStateCopy, activeAdStateCopy.adDuration);\n }\n\n onAdSkipped(_ad: AdInfo) {\n if (!this.activeAdBreakState || !this.activeAdState) {\n return;\n }\n\n const activeAdStateCopy = {...this.activeAdState};\n activeAdStateCopy.skipped = 1;\n activeAdStateCopy.skipPosition = this.currentTime;\n activeAdStateCopy.skipPercentage = Utils.calculatePercentage(\n activeAdStateCopy.skipPosition,\n this.activeAdState.adDuration,\n );\n this.resetActiveAd();\n this.completeAd(this.activeAdBreakState, activeAdStateCopy, activeAdStateCopy.skipPosition);\n }\n\n onAdError(payload: AdErrorPayload) {\n const adBreakSample = buildInitialActiveAdBreakState(payload.adBreakInfo);\n\n const transformedError = this.analytics.transformError(\n {code: payload.code, message: payload.message, severity: 'CRITICAL'},\n payload,\n );\n\n adBreakSample.errorCode = transformedError.code;\n adBreakSample.errorData = tryJSONStringify({code: payload.code, message: payload.message});\n adBreakSample.errorMessage = transformedError.message;\n adBreakSample.errorSeverity = transformedError.severity;\n\n let activeAdState: ActiveAdState | undefined;\n let exitPosition: number | undefined;\n if (this.activeAdState && payload.activeAdId && this.activeAdState.adId === payload.activeAdId) {\n activeAdState = this.activeAdState;\n exitPosition = this.currentTime;\n activeAdState.errorPosition = this.currentTime;\n activeAdState.errorPercentage = Utils.calculatePercentage(activeAdState.errorPosition, activeAdState.adDuration);\n }\n this.completeAd(adBreakSample, activeAdState, exitPosition);\n }\n\n onAdClicked(payload: AdClickedPayload) {\n if (!this.activeAdState) {\n return;\n }\n this.activeAdState.adClickthroughUrl = payload.clickThroughUrl;\n this.activeAdState.clicked = 1;\n this.activeAdState.clickPosition = this.currentTime;\n this.activeAdState.clickPercentage = Utils.calculatePercentage(\n this.activeAdState.clickPosition,\n this.activeAdState.adDuration,\n );\n }\n\n onAdQuartile(payload: AdQuartilePayload) {\n if (!this.activeAdState) {\n return;\n }\n if (payload.quartile === AdQuartile.FIRST_QUARTILE) {\n this.activeAdState.quartile1 = 1;\n } else if (payload.quartile === AdQuartile.MIDPOINT) {\n this.activeAdState.midpoint = 1;\n } else if (payload.quartile === AdQuartile.THIRD_QUARTILE) {\n this.activeAdState.quartile3 = 1;\n }\n }\n\n onBeforeUnload() {\n if (this.onBeforeUnLoadEvent) {\n return;\n }\n this.onBeforeUnLoadEvent = true;\n if (!this.activeAdState || !this.activeAdBreakState) {\n return;\n }\n\n const activeAdStateCopy = {...this.activeAdState};\n activeAdStateCopy.closed = 1;\n activeAdStateCopy.closePosition = this.currentTime;\n activeAdStateCopy.closePercentage = Utils.calculatePercentage(\n activeAdStateCopy.closePosition,\n activeAdStateCopy.adDuration,\n );\n this.resetActiveAd();\n this.completeAd(this.activeAdBreakState, activeAdStateCopy, activeAdStateCopy.closePosition);\n }\n\n private sendAnalyticsRequest(activeAdBreakState: ActiveAdBreakState, activeAdState?: ActiveAdState) {\n const adSample: AdSample = {\n // set common fields from playback sample (if already created)\n ...buildAdSample(this.analytics.sample),\n // set ad break fields\n ...activeAdBreakState,\n // set ad fields (if any)\n ...(activeAdState || buildInitialActiveAdState()),\n };\n\n const moduleInfo = this.adapter.getAdModuleInfo();\n adSample.platform = 'web';\n adSample.analyticsVersion = VERSION;\n adSample.adModule = moduleInfo.name;\n adSample.adModuleVersion = moduleInfo.version;\n adSample.autoplay = this.adapter.getAutoPlay();\n adSample.pageLoadType = Utils.getPageLoadType();\n\n adSample.time = Date.now();\n adSample.adImpressionId = generateUUID();\n adSample.percentageInViewport = Utils.calculatePercentage(adSample.timeInViewport, adSample.timePlayed);\n this.analytics.backend.sendAdRequest(adSample);\n }\n\n private updatePlayingTime(activeAdState: ActiveAdState) {\n const timestamp = Date.now();\n if (this.beginPlayingTimestamp && this.isPlaying) {\n if (activeAdState.timePlayed !== undefined) {\n activeAdState.timePlayed += timestamp - this.beginPlayingTimestamp;\n }\n if (this.isContainerInViewport() && this.enterViewportTimestamp && activeAdState.timeInViewport !== undefined) {\n activeAdState.timeInViewport += timestamp - this.enterViewportTimestamp;\n }\n }\n }\n\n private startAd(activeAdState: ActiveAdState) {\n activeAdState.started = 1;\n activeAdState.timePlayed = 0;\n activeAdState.timeInViewport = 0;\n activeAdState.adPodPosition = this.adPodPosition;\n const timestamp = Date.now();\n this.beginPlayingTimestamp = timestamp;\n this.enterViewportTimestamp = this.isContainerInViewport() ? timestamp : undefined;\n this.isPlaying = true;\n this.currentTime = 0;\n this.adPodPosition++;\n this.currentTimeInterval = setInterval(() => {\n try {\n if (activeAdState?.adDuration != null && activeAdState.adDuration > 0 && this.adapter.isLinearAdActive()) {\n this.currentTime = Utils.calculateTime(Math.max(this.adapter.currentTime(), 0));\n }\n } catch (e) {\n logger.log('AdStarted monitoring interval failed and got cleared', e);\n this.resetActiveAd();\n }\n }, AdAnalytics.TIMEOUT_CURRENT_TIME_INTERVAL);\n }\n\n private completeAd(\n activeAdBreakState: ActiveAdBreakState,\n activeAdState: ActiveAdState = buildInitialActiveAdState(),\n exitPosition?: number,\n ) {\n activeAdState.exitPosition = exitPosition;\n activeAdState.playPercentage = Utils.calculatePercentage(activeAdState.exitPosition, activeAdState.adDuration);\n\n // Fallback to set quartile properties (if not set yet)\n // For players that don't emit native quartile events (THEOplayer) we calculate quartile properties based on playPercentage\n if (isNotNullish(activeAdState.playPercentage)) {\n if (activeAdState.quartile1 === 0 && activeAdState.playPercentage >= 25) {\n activeAdState.quartile1 = 1;\n }\n if (activeAdState.midpoint === 0 && activeAdState.playPercentage >= 50) {\n activeAdState.midpoint = 1;\n }\n if (activeAdState.quartile3 === 0 && activeAdState.playPercentage >= 75) {\n activeAdState.quartile3 = 1;\n }\n }\n\n // reset startupTimestamp for the next ad, in case there are multiple ads in one ad break\n this.adStartupTimestamp = Date.now();\n this.updatePlayingTime(activeAdState);\n this.isPlaying = false;\n this.sendAnalyticsRequest(activeAdBreakState, activeAdState);\n }\n\n private resetActiveAd() {\n this.clearCurrentTimeInterval();\n this.activeAdState = undefined;\n }\n\n private clearCurrentTimeInterval() {\n clearInterval(this.currentTimeInterval);\n delete this.currentTime;\n }\n}\n\n/**\n * Used to track the state of the active ad break.\n *\n * It is partial of {@link AdSample} because it's purpose is to build the final {@link AdSample}.\n */\ntype ActiveAdBreakState = Pick<\n AdSample,\n | 'adFallbackIndex'\n | 'adIdPlayer'\n | 'adIsPersistent'\n | 'adOffset'\n | 'adPosition'\n | 'adPreloadOffset'\n | 'adReplaceContentDuration'\n | 'adScheduleTime'\n | 'adTagPath'\n | 'adTagServer'\n | 'adTagType'\n | 'adTagUrl'\n | 'errorCode'\n | 'errorData'\n | 'errorMessage'\n | 'errorSeverity'\n | 'manifestDownloadTime'\n>;\n\nexport function buildInitialActiveAdBreakState(adBreakInfo?: AdBreakInfo): ActiveAdBreakState {\n const state: ActiveAdBreakState = {adFallbackIndex: 0};\n\n if (isNullish(adBreakInfo)) {\n return state;\n }\n\n state.adIdPlayer = adBreakInfo.id;\n state.adReplaceContentDuration = Utils.calculateTimeWithUndefined(adBreakInfo.replaceContentDuration);\n state.adIsPersistent = adBreakInfo.persistent;\n state.adTagType = adBreakInfo.tagType;\n state.adTagUrl = adBreakInfo.tagUrl;\n state.adPreloadOffset = Utils.calculateTimeWithUndefined(adBreakInfo.preloadOffset);\n state.adFallbackIndex = adBreakInfo.fallbackIndex ?? 0;\n state.manifestDownloadTime = Utils.calculateTimeWithUndefined(adBreakInfo.manifestDownloadTime);\n\n if (adBreakInfo.position === 'pre' || adBreakInfo.position === 'post') {\n state.adPosition = adBreakInfo.position;\n } else if (isNotNullish(adBreakInfo.position)) {\n state.adPosition = 'mid';\n state.adOffset = adBreakInfo.position;\n }\n\n if (isNotNullish(state.adTagUrl)) {\n try {\n const adTagUrl = new URL(state.adTagUrl);\n state.adTagServer = adTagUrl.hostname;\n state.adTagPath = adTagUrl.pathname;\n } catch {\n // Invalid URL, leave fields undefined\n }\n }\n\n if (isFiniteNumber(adBreakInfo.scheduleTime)) {\n state.adScheduleTime = Utils.calculateTime(adBreakInfo.scheduleTime);\n }\n\n return state;\n}\n\n/**\n * Used to track the state of the active ad in ad break.\n *\n * It is partial of {@link AdSample} because it's purpose is to build the final {@link AdSample}.\n */\ntype ActiveAdState = Pick<\n AdSample,\n | 'adClickthroughUrl'\n | 'adDescription'\n | 'adDuration'\n | 'adId'\n | 'adPlaybackHeight'\n | 'adPlaybackWidth'\n | 'adPodPosition'\n | 'adSkipAfter'\n | 'adSkippable'\n | 'adStartupTime'\n | 'adSystem'\n | 'adTitle'\n | 'advertiserName'\n | 'apiFramework'\n | 'clicked'\n | 'clickPercentage'\n | 'clickPosition'\n | 'closed'\n | 'closePercentage'\n | 'closePosition'\n | 'completed'\n | 'creativeAdId'\n | 'creativeId'\n | 'errorPercentage'\n | 'errorPosition'\n | 'exitPosition'\n | 'isLinear'\n | 'mediaPath'\n | 'mediaServer'\n | 'mediaUrl'\n | 'midpoint'\n | 'minSuggestedDuration'\n | 'playPercentage'\n | 'quartile1'\n | 'quartile3'\n | 'skipped'\n | 'skipPercentage'\n | 'skipPosition'\n | 'started'\n | 'streamFormat'\n | 'surveyUrl'\n | 'timeInViewport'\n | 'timePlayed'\n | 'universalAdIdRegistry'\n | 'universalAdIdValue'\n | 'videoBitrate'\n | 'wrapperAdsCount'\n>;\n\nexport function buildInitialActiveAdState(adInfo?: AdInfo): ActiveAdState {\n const state: ActiveAdState = {\n clicked: 0,\n closed: 0,\n completed: 0,\n midpoint: 0,\n quartile1: 0,\n quartile3: 0,\n skipped: 0,\n started: 0,\n };\n\n if (isNullish(adInfo)) {\n return state;\n }\n\n state.adClickthroughUrl = adInfo.clickThroughUrl;\n state.adId = adInfo.id;\n state.mediaUrl = adInfo.mediaUrl;\n state.isLinear = adInfo.isLinear;\n state.adPlaybackHeight = adInfo.height;\n state.adPlaybackWidth = adInfo.width;\n state.streamFormat = adInfo.mimeType;\n\n if (isNotNullish(state.mediaUrl)) {\n try {\n const mediaUrl = new URL(state.mediaUrl);\n state.mediaPath = mediaUrl.pathname;\n state.mediaServer = mediaUrl.hostname;\n } catch {\n // Invalid URL, leave fields undefined\n }\n }\n\n if (isNotNullish(adInfo.bitrate)) {\n state.videoBitrate = adInfo.bitrate * 1000;\n }\n\n const vastData = adInfo.vastData;\n if (isNotNullish(vastData)) {\n state.adSystem = vastData.adSystem;\n state.advertiserName = vastData.advertiserName;\n state.apiFramework = vastData.apiFramework;\n state.creativeAdId = vastData.creativeAdId;\n state.creativeId = vastData.creativeId;\n state.universalAdIdRegistry = vastData.universalAdIdRegistry;\n state.universalAdIdValue = vastData.universalAdIdValue;\n state.adDescription = vastData.adDescription;\n state.minSuggestedDuration = Utils.calculateTimeWithUndefined(vastData.minSuggestedDuration);\n state.surveyUrl = vastData.surveyUrl;\n state.adTitle = vastData.adTitle;\n state.wrapperAdsCount = vastData.wrapperAdsCount;\n }\n\n if (isNotNullish(adInfo.skippableAfter)) {\n state.adSkipAfter =\n adInfo.skippableAfter === -1 ? adInfo.skippableAfter : Utils.calculateTime(adInfo.skippableAfter);\n }\n\n state.adSkippable = adInfo.skippable ?? (isNotNullish(state.adSkipAfter) ? state.adSkipAfter >= 0 : undefined);\n state.adDuration = Utils.calculateTimeWithUndefined(adInfo.duration);\n\n return state;\n}\n","import {InternalAdapterAPI} from '../adapters/internal/InternalAdapterAPI';\nimport {AD_TYPE} from '../enums/AdType';\nimport {ErrorCode} from '../enums/ErrorCode';\nimport {PlayerSize} from '../enums/PlayerSize';\nimport {VideoStartFailedReason} from '../enums/VideoStartFailedReason';\nimport {ErrorDetailTrackingSettingsProvider} from '../features/errordetails/ErrorDetailTracking';\nimport {OnErrorDetailEventObject} from '../features/errordetails/OnErrorDetailEventObject';\nimport {FeatureManager} from '../features/FeatureManager';\nimport type {AnalyticsConfig, AnalyticsError} from '../types/AnalyticsConfig';\nimport {AuthenticationCallback} from '../types/AuthenticationCallback';\nimport {CustomDataValues, extractCustomDataFieldsOnly} from '../types/CustomDataValues';\nimport type {QualityChangeEvent} from '../types/EventData';\nimport * as EventData from '../types/EventData';\nimport {FeatureConfigContainer} from '../types/FeatureConfigContainer';\nimport {PlaybackInfo} from '../types/PlaybackInfo';\nimport {Sample} from '../types/Sample';\nimport type {SourceMetadata} from '../types/SourceMetadata';\nimport Timespan from '../types/Timespan';\nimport {\n applySourceMetadataToAnalyticsConfig,\n getDeviceInformationFromAnalyticsConfig,\n getDomainFromAnalyticsConfig,\n guardAgainstDuplicatedUserId,\n guardConfigChangeAgainstMissingIsLive,\n guardConfigChangeAgainstMissingTitle,\n mergeAnalyticsConfig,\n} from '../utils/analyticsConfigUtils';\nimport {CodecHelper} from '../utils/CodecHelper';\nimport {globalScope} from '../utils/globalScope';\nimport {\n getGlobalNavigatorLanguage,\n getGlobalNavigatorUserAgent,\n getGlobalScreenDimensions,\n hasGlobalWebOSApi,\n} from '../utils/globalScopeUtils';\nimport {logger} from '../utils/Logger';\nimport {isFiniteNumber, isNumber} from '../utils/numberUtils';\nimport {clearSampleStateValues, getDefaultSamplePath} from '../utils/sampleUtils';\nimport {isBlank, isValidString} from '../utils/stringUtils';\nimport * as Utils from '../utils/Utils';\nimport {isErrorSeverity, isNotNullish, isNullish, tryJSONStringify} from '../utils/Utils';\nimport {generateUUID} from '../utils/uuidUtils';\nimport {VERSION} from '../utils/Version';\nimport {getWebOSTVModelName} from '../utils/WebOSUtils';\n\nimport {AdAnalytics} from './AdAnalytics';\nimport {Backend} from './Backend';\nimport {BackendFactory} from './BackendFactory';\nimport {EventDispatcher, Subscribable} from './EventDispatcher';\nimport {IdenticalErrorReportingLimiter} from './IdenticalErrorReportingLimiter';\nimport {NoOpBackend} from './NoOpBackend';\nimport {SessionPersistenceHandler} from './SessionPersistenceHandler';\nimport {\n isSsaiEngagementErrorData,\n isSsaiEngagementQuartileData,\n isSsaiEngagementStartedData,\n SsaiEngagementInteractionData,\n} from './ssai/ssaiEngagementInteractionData';\nimport {createErrorAdSample, createQuartileAdSample, createStartedAdSample} from './ssai/ssaiUtils';\n\nexport class Analytics {\n get version(): string {\n return VERSION;\n }\n\n static version: string = VERSION;\n\n private readonly adAnalytics: AdAnalytics | undefined;\n\n sample: Sample;\n\n private hasSentStartupSample = false;\n backend!: Backend;\n readonly errorDetailTrackingSettingsProvider: ErrorDetailTrackingSettingsProvider;\n\n private config: AnalyticsConfig;\n private droppedSampleFrames = 0;\n /**\n * Used to save and store player startup time once the \"setup sample\" is created, to pick it up and use it to set\n * the \"startup sample\" property \"startupTime\" as a sum of player and video startup time.\n */\n private playerStartupTime = 0;\n\n private readonly authenticationCallback: AuthenticationCallback = {\n authenticationCompleted: (success: boolean, featureConfigs?: FeatureConfigContainer) => {\n this.featureManager.configureFeatures(success, featureConfigs);\n },\n };\n\n // used only in tests to inject mocks\n constructor(\n initialAnalyticsConfig: AnalyticsConfig,\n private readonly adapter: InternalAdapterAPI,\n private readonly backendFactory: BackendFactory,\n private readonly sessionHandler: SessionPersistenceHandler,\n private readonly featureManager: FeatureManager<FeatureConfigContainer>,\n private readonly onErrorDetailEventDispatcher: EventDispatcher<OnErrorDetailEventObject>,\n private readonly identicalErrorReportingLimiter: IdenticalErrorReportingLimiter,\n ) {\n this.config = initialAnalyticsConfig;\n this.sessionHandler = new SessionPersistenceHandler(this.config);\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const that = this;\n this.errorDetailTrackingSettingsProvider = {\n get domain() {\n return getDomainFromAnalyticsConfig(that.config);\n },\n get licenseKey() {\n return that.config.key ?? '';\n },\n get impressionId() {\n return that.getCurrentImpressionId() ?? '';\n },\n get collectorConfig() {\n return that.config.config;\n },\n };\n\n const licenseKeyReceivedUnsubscriber = this.adapter.onLicenseKeyReceived.subscribe(\n (eventArgs: {licenseKey: string}) => {\n if (!this.config.key) {\n this.config.key = eventArgs.licenseKey;\n }\n licenseKeyReceivedUnsubscriber();\n },\n );\n\n this.sample = this.buildInitialSample();\n this.droppedSampleFrames = 0;\n this.init();\n this.setupStateMachineCallbacks();\n\n // initialize adapter (start to listen to the player events and call the callbacks accordingly)\n const features = this.adapter.initialize(this);\n this.featureManager.registerFeatures(features);\n\n if (this.adapter.adModule) {\n // this needs to be called after the adapter has been initialized and has created adModule (if any)\n this.adAnalytics = new AdAnalytics(this, this.adapter.adModule);\n }\n }\n\n get errorDetailSubscribable(): Subscribable<OnErrorDetailEventObject> {\n return this.onErrorDetailEventDispatcher;\n }\n\n init() {\n if (\n this.adapter.supportsDeferredLicenseLoading !== true &&\n (!isValidString(this.config.key) || isBlank(this.config.key))\n ) {\n logger.errorMessageToUser('Invalid analytics license key provided');\n return;\n }\n\n logger.initialize(this.config.debug);\n\n this.featureManager.resetFeatures();\n\n const domain = getDomainFromAnalyticsConfig(this.config);\n this.backend = this.backendFactory.createBackend(\n this.config,\n {key: this.config.key, domain, version: VERSION},\n this.adapter,\n this.authenticationCallback,\n );\n\n this.hasSentStartupSample = false;\n this.identicalErrorReportingLimiter.reset();\n\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n this.sample.impressionId = generateUUID();\n this.sample.userId = this.sessionHandler.userId;\n\n if (this.adapter.videoCompletionTracker) {\n this.adapter.videoCompletionTracker.reset();\n }\n\n this.adapter.qualityChangeService.resetValues();\n this.adapter.ssaiService.resetSourceRelatedState();\n }\n\n setConfigParameters() {\n this.sample.key = this.config.key;\n this.sample.playerKey = this.config.playerKey;\n if (this.config.player) {\n this.sample.player = this.config.player;\n }\n this.sample.domain = getDomainFromAnalyticsConfig(this.config);\n\n this.sample.deviceInformation = getDeviceInformationFromAnalyticsConfig(this.config);\n\n this.sample.isLive = isNotNullish(this.config.isLive) ? this.config.isLive : false;\n\n this.sample.cdnProvider = this.config.cdnProvider;\n this.sample.videoId = this.config.videoId;\n this.sample.videoTitle = this.config.title;\n this.sample.customUserId = this.config.userId ?? this.config.customUserId;\n\n Utils.transferCustomDataFields(this.config, this.sample);\n\n this.sample.experimentName = this.config.experimentName;\n }\n\n setAutoDetectedDeviceInformation(): void {\n // do not overwrite existing model value (set through config)\n if (isNotNullish(this.sample.deviceInformation?.model)) {\n return;\n }\n\n if (!hasGlobalWebOSApi()) return;\n\n const modelName = getWebOSTVModelName();\n if (isNullish(modelName)) return;\n\n this.sample.deviceInformation = this.sample.deviceInformation ?? {};\n this.sample.deviceInformation.model = modelName;\n }\n\n private setupStateMachineCallbacks() {\n // All of these are called in the onLeaveState Method.\n // So it's the last sample\n this.adapter.stateMachineCallbacks.setup = (duration: number, state: string) => {\n logger.log(\n 'Setup bitmovin analytics ' + this.sample.analyticsVersion + ' with impressionId: ' + this.sample.impressionId,\n );\n\n this.setDuration(duration);\n this.setState(state);\n this.sample.playerStartupTime = duration;\n this.playerStartupTime = this.sample.playerStartupTime;\n\n const navigationStart = globalScope.performance?.timing?.navigationStart;\n if (isNotNullish(navigationStart) && isFiniteNumber(navigationStart)) {\n // round the final time to a whole number to avoid unnecessary precision (performance API returns a high-precision timestamp as double)\n const pageLoadTime = Math.round(Date.now() - globalScope.performance.timing.navigationStart);\n this.sample.pageLoadTime = pageLoadTime;\n }\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.startup = (duration: number, state: string) => {\n this.setState(state);\n this.sample.supportedVideoCodecs = CodecHelper.supportedVideoFormats;\n // videoStartupTime has to be > 0 on startup sample\n // it is used to mark a successfull impression and billing depends on it\n const sanitizeVideoStartupTime = Math.max(duration, 1);\n this.setDuration(sanitizeVideoStartupTime);\n this.sample.videoStartupTime = sanitizeVideoStartupTime;\n this.sample.startupTime = (this.playerStartupTime || 0) + sanitizeVideoStartupTime;\n\n this.sample.autoplay = this.adapter.getAutoPlay();\n\n const drmPerformance = this.adapter.getDrmPerformanceInfo();\n if (isNotNullish(drmPerformance)) {\n this.sample.drmType = drmPerformance.drmType;\n this.sample.drmLoadTime = drmPerformance.drmLoadTime;\n }\n\n const {videoBitrate, audioBitrate} = this.adapter.getCurrentPlaybackInfo();\n // set the flag to allow quality change events after startup and try to set the startup bitrate values (if any)\n // as the initial ones, to be able to compare them with future quality changes\n this.adapter.qualityChangeService.setStartupHasFinished(videoBitrate, audioBitrate);\n\n this.hasSentStartupSample = true;\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.programChange = (sourceMetadata: SourceMetadata) => {\n // reset analytics\n // player is already loaded, so it is irrelevant for the program change startup sample\n this.playerStartupTime = 0;\n\n // apply source metadata to config\n this.config = applySourceMetadataToAnalyticsConfig(this.config, sourceMetadata);\n\n // reset sample to init values\n this.sample = this.buildInitialSample();\n // apply a source metadata path to the sample (if any)\n this.sample.path = isValidString(sourceMetadata.path) ? sourceMetadata.path : getDefaultSamplePath();\n\n // reinitialize to finish reset of the Analytics module\n this.init();\n\n // build startup \"programchange\" sample\n this.setState('programchange');\n this.sample.isProgramChange = true;\n this.sample.supportedVideoCodecs = CodecHelper.supportedVideoFormats;\n // videoStartupTime has to be > 0 on the startup sample\n // it is used to mark a successful impression and billing depends on it\n const programChangeVideoStartupTime = 1;\n this.setDuration(programChangeVideoStartupTime);\n this.sample.videoStartupTime = programChangeVideoStartupTime;\n this.sample.startupTime = programChangeVideoStartupTime; // is not affected now by player startup time\n\n this.sample.autoplay = this.adapter.getAutoPlay();\n\n // DRM load time is only important when we load the source, DRM request does not happen between active playback\n // so it can't happen during the program change\n this.sample.drmType = undefined;\n this.sample.drmLoadTime = undefined;\n\n const {videoBitrate, audioBitrate} = this.adapter.getCurrentPlaybackInfo();\n // set the flag to allow quality change events after startup and try to set the startup bitrate values (if any)\n // as the initial ones, to be able to compare them with future quality changes\n this.adapter.qualityChangeService.setStartupHasFinished(videoBitrate, audioBitrate);\n\n this.hasSentStartupSample = true;\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.updateSourceMetadata = (sourceMetadata: SourceMetadata) => {\n // apply source metadata to config\n this.config = applySourceMetadataToAnalyticsConfig(this.config, sourceMetadata);\n // new config should be immediately applied to the current sample\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n // apply a source metadata path to the sample (if any)\n this.sample.path = isValidString(sourceMetadata.path) ? sourceMetadata.path : getDefaultSamplePath();\n };\n\n this.adapter.stateMachineCallbacks.playing = (duration: number, state: string) => {\n this.setDuration(duration);\n this.setState(state);\n this.sample.played = duration;\n this.setCompletionValues();\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.unload = (duration: number, state: string) => {\n let videoStartForClosedState = this.sample.videoTimeStart;\n if (state === 'playing') {\n this.setDuration(duration);\n this.setState(state);\n this.sample.played = duration;\n this.setCompletionValues();\n if (isNumber(this.sample.videoTimeEnd)) {\n videoStartForClosedState = this.sample.videoTimeEnd;\n }\n\n this.backend.sendUnloadRequest(this.sample);\n clearSampleStateValues(this.sample);\n }\n\n if (this.hasSentStartupSample) {\n this.setVideoTimeStart(videoStartForClosedState);\n this.setVideoTimeEnd(videoStartForClosedState);\n this.setState('closed');\n\n this.backend.sendUnloadRequest(this.sample);\n clearSampleStateValues(this.sample);\n }\n };\n\n this.adapter.stateMachineCallbacks.heartbeat = (duration, state, heartbeatPayload) => {\n this.setState(state);\n this.setDuration(duration);\n\n this.sample = {\n ...this.sample,\n ...heartbeatPayload,\n };\n\n if (state === 'playing') {\n this.setCompletionValues();\n }\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.qualitychange = (event: QualityChangeEvent) => {\n this.adapter.qualityChangeService.startResetInterval();\n this.adapter.qualityChangeService.increaseCounter();\n\n if (this.adapter.qualityChangeService.hasExceededQualityChangeThreshold()) {\n this.adapter.stateMachineCallbacks.error({\n code: ErrorCode.QUALITY_CHANGE_THRESHOLD_EXCEEDED.code,\n message: ErrorCode.QUALITY_CHANGE_THRESHOLD_EXCEEDED.message,\n errorSeverity: ErrorCode.QUALITY_CHANGE_THRESHOLD_EXCEEDED.errorSeverity,\n legacyData: undefined,\n data: {},\n currentTime: event.currentTime,\n });\n return;\n }\n\n this.setState('qualitychange');\n this.setDuration(0);\n this.adapter.stateMachineCallbacks.setVideoTimeEndFromEvent(event);\n this.adapter.stateMachineCallbacks.setVideoTimeStartFromEvent(event);\n this.adapter.stateMachineCallbacks.updateSampleQualityInfo(event);\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.updateSampleQualityInfo = (event: QualityChangeEvent) => {\n if (event.type === 'audio') {\n if (isNumber(event.bitrate)) {\n this.sample.audioBitrate = event.bitrate;\n }\n if (isValidString(event.codec)) {\n this.sample.audioCodec = event.codec;\n }\n } else if (event.type === 'video') {\n if (isNumber(event.bitrate)) {\n this.sample.videoBitrate = event.bitrate;\n }\n if (isValidString(event.codec)) {\n this.sample.videoCodec = event.codec;\n }\n if (isNumber(event.height)) {\n this.sample.videoPlaybackHeight = event.height;\n }\n if (isNumber(event.width)) {\n this.sample.videoPlaybackWidth = event.width;\n }\n }\n };\n\n this.adapter.stateMachineCallbacks.audiotrack_changing = () => {\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.pause = (duration: number, state: string) => {\n this.setDuration(duration);\n this.setState(state);\n\n this.sample.paused = duration;\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.seeking = (duration: number) => {\n this.setDuration(duration);\n this.setState('seeking');\n this.sample.seeked = duration;\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.buffering = (duration: number, state: string) => {\n this.setDuration(duration);\n this.setState(state);\n\n this.sample.buffered = duration;\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.videoStartFailed = (duration, reason) => {\n this.setState('startup');\n this.sample.videoStartFailed = true;\n this.sample.videoStartFailedReason = reason;\n this.sample.duration = duration;\n\n if (reason === VideoStartFailedReason.PLAYER_ERROR) {\n // on player error we should not send a video startup sample\n return;\n }\n\n if (reason === VideoStartFailedReason.TIMEOUT) {\n this.sample.errorCode = ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.code;\n this.sample.errorMessage = ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.message;\n this.sample.errorSeverity = ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.errorSeverity;\n\n this.onErrorDetailEventDispatcher.dispatch({\n code: ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.code,\n message: ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.message,\n severity: ErrorCode.VIDEO_STARTUP_TIMEOUT_REACHED.errorSeverity,\n });\n }\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.error = (event: Readonly<EventData.ErrorEvent>) => {\n const error = this.transformError(\n {code: event.code, message: event.message, severity: event.errorSeverity ?? 'CRITICAL'},\n event.originalError,\n );\n\n if (error.code && !this.identicalErrorReportingLimiter.shouldReportError(error.code, error.severity)) {\n logger.log(\n `Bitmovin Analytics: Processing of the error with code ${error.code} was ignored because the error limit was exceeded.`,\n );\n return;\n }\n\n this.adapter.stateMachineCallbacks.setVideoTimeEndFromEvent(event);\n this.adapter.stateMachineCallbacks.setVideoTimeStartFromEvent(event);\n\n this.setState('error');\n this.setDuration(0);\n this.sample.errorCode = error.code;\n this.sample.errorMessage = error.message;\n this.sample.errorSeverity = error.severity;\n this.sample.errorData = tryJSONStringify(event.legacyData);\n this.sample.errorSegments = this.adapter.getSegmentInfo().map((s) => s.name);\n\n if (this.adapter.onError) {\n this.adapter.onError();\n }\n\n this.onErrorDetailEventDispatcher.dispatch({\n code: error.code,\n message: error.message,\n severity: error.severity,\n errorData: event.data,\n });\n\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.ad = (duration: number, state: string) => {\n this.setDuration(duration);\n this.setState(state);\n this.sample.ad = AD_TYPE.CSAI;\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.mute = () => {\n this.sample.isMuted = true;\n };\n\n this.adapter.stateMachineCallbacks.unMute = () => {\n this.sample.isMuted = false;\n };\n\n this.adapter.stateMachineCallbacks.subtitle_changing = () => {\n this.sendSample();\n };\n\n this.adapter.stateMachineCallbacks.setVideoTimeEndFromEvent = (analyticsEventBase) => {\n // if we don't have the current playback time, skip and do nothing\n if (!isNumber(analyticsEventBase?.currentTime)) {\n return;\n }\n\n this.setVideoTimeEnd(Utils.calculateTime(analyticsEventBase.currentTime));\n };\n\n this.adapter.stateMachineCallbacks.setVideoTimeStartFromEvent = (analyticsEventBase) => {\n // if we don't have the current playback time, skip and do nothing\n if (!isNumber(analyticsEventBase?.currentTime)) {\n return;\n }\n\n this.setVideoTimeStart(Utils.calculateTime(analyticsEventBase.currentTime));\n };\n\n this.adapter.stateMachineCallbacks.manualSourceChange = (event: {config: AnalyticsConfig}) => {\n this.adapter.resetSourceRelatedState();\n this.sample = this.buildInitialSample();\n this.droppedSampleFrames = 0;\n this.playerStartupTime = 0;\n this.config = Object.keys(event.config).length > 0 ? event.config : this.config;\n this.init();\n };\n\n this.adapter.stateMachineCallbacks.initialSourceChange = (event: {config: AnalyticsConfig}) => {\n this.config = event.config;\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n };\n\n // The video has ended and we set up for a new impression\n this.adapter.stateMachineCallbacks.end = () => {\n // !!!! THIS IS OLD AND WRONG IMPLEMENTATION !!!!\n // (check deprecation comment on callback)\n this.sample = this.buildInitialSample();\n this.droppedSampleFrames = 0;\n this.playerStartupTime = 0;\n this.init();\n };\n\n this.adapter.stateMachineCallbacks.release = () => {\n this.backend = new NoOpBackend();\n this.adAnalytics?.release();\n this.adapter.qualityChangeService.stopResetInterval();\n this.identicalErrorReportingLimiter.reset();\n };\n\n this.adapter.stateMachineCallbacks.customdatachange = (_duration, _state, eventData) => {\n if (isNotNullish(eventData?.customDataValues)) {\n this.changeCustomData(eventData.customDataValues);\n }\n };\n }\n\n sourceChange = (config: AnalyticsConfig | null | undefined) => {\n logger.log('Processing Source Change for Analytics', config);\n if (isNullish(config)) {\n this.adapter.sourceChange(this.config);\n return;\n }\n\n guardConfigChangeAgainstMissingTitle(this.config, config);\n guardConfigChangeAgainstMissingIsLive(this.config, config);\n guardAgainstDuplicatedUserId(config);\n\n const newConfig = mergeAnalyticsConfig(this.config, config);\n this.adapter.sourceChange(newConfig);\n };\n\n setCustomDataOnce = (values: CustomDataValues) => {\n // save old config to be able to return previous custom data values once the sample is sent\n const oldConfig = {...this.config};\n\n this.setState('customdatachange');\n\n this.sendSample(values);\n // this method doesn't call changeCustomData() second time because in that method we have check for null values\n // to prevent overriding existing customData values with null if some field in object doesn't have value\n // because of that if some customData field had previous value null and it got changed to something else\n // it will not be possible to return it back to null using that method\n this.config = {...oldConfig};\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n };\n\n setCustomData = (values: CustomDataValues) => {\n this.adapter.setCustomData(values);\n };\n\n getCurrentImpressionId = (): string | undefined => {\n return this.sample.impressionId;\n };\n\n getUserId = (): string => {\n return this.sessionHandler.userId;\n };\n\n setDuration(duration: number) {\n this.sample.duration = duration;\n }\n\n setState(state: string) {\n this.sample.state = state;\n }\n\n setPlaybackInfoFromAdapter() {\n const info = this.adapter.getCurrentPlaybackInfo();\n if (!info) {\n return;\n }\n\n // if set, we always apply `config.isLive` in favor of `info.isLive`\n this.sample.isLive = isNotNullish(this.config.isLive) ? this.config.isLive : info.isLive;\n // if `isLive` is still not defined, we set it to default `false` value\n if (isNullish(this.sample.isLive)) {\n this.sample.isLive = false;\n }\n\n if (isValidString(info.size)) {\n this.sample.size = info.size;\n }\n if (isValidString(info.playerTech)) {\n this.sample.playerTech = info.playerTech;\n }\n if (isNumber(info.videoDuration)) {\n this.sample.videoDuration = Utils.calculateTime(info.videoDuration || 0);\n }\n if (isValidString(info.streamFormat)) {\n this.sample.streamFormat = info.streamFormat;\n }\n if (isValidString(info.mpdUrl)) {\n this.sample.mpdUrl = info.mpdUrl;\n }\n if (isValidString(info.m3u8Url)) {\n this.sample.m3u8Url = info.m3u8Url;\n }\n if (isValidString(info.progUrl)) {\n this.sample.progUrl = info.progUrl;\n }\n if (isNumber(info.videoWindowWidth)) {\n this.sample.videoWindowWidth = info.videoWindowWidth;\n }\n if (isNumber(info.videoWindowHeight)) {\n this.sample.videoWindowHeight = info.videoWindowHeight;\n }\n if (isNumber(info.screenHeight)) {\n this.sample.screenHeight = info.screenHeight;\n }\n if (isNumber(info.screenWidth)) {\n this.sample.screenWidth = info.screenWidth;\n }\n if (Utils.isBoolean(info.isMuted)) {\n this.sample.isMuted = info.isMuted;\n }\n if (Utils.isBoolean(info.isCasting)) {\n this.sample.isCasting = info.isCasting;\n }\n if (isValidString(info.castTech)) {\n this.sample.castTech = info.castTech;\n }\n if (isValidString(info.videoTitle) && !this.config.title) {\n this.sample.videoTitle = info.videoTitle;\n }\n if (isValidString(info.audioCodec)) {\n this.sample.audioCodec = info.audioCodec;\n }\n if (isValidString(info.videoCodec)) {\n this.sample.videoCodec = info.videoCodec;\n }\n if (isValidString(info.audioLanguage)) {\n this.sample.audioLanguage = info.audioLanguage;\n }\n if (Utils.isBoolean(info.subtitleEnabled)) {\n this.sample.subtitleEnabled = info.subtitleEnabled;\n }\n if (isValidString(info.subtitleLanguage)) {\n this.sample.subtitleLanguage = info.subtitleLanguage;\n } else {\n this.sample.subtitleLanguage = undefined;\n }\n if (isNumber(info.droppedFrames)) {\n this.sample.droppedFrames = Math.max(info.droppedFrames - this.droppedSampleFrames, 0);\n this.droppedSampleFrames = info.droppedFrames;\n }\n }\n\n sendSample(customDataOnceValues?: CustomDataValues) {\n this.setPlaybackInfoFromAdapter();\n this.sample.time = Utils.getCurrentTimestamp();\n\n // get current download speed info from the adapter and set it on the sample before sending it\n this.sample.downloadSpeedInfo = this.adapter.getDownloadSpeedInfo();\n // reset current download speed info measures in the adapter to start fresh for the next sample,\n // so we always have the info for the current sample only\n this.adapter.resetDownloadSpeedInfoMeasures();\n\n this.adapter.ssaiService.manipulate(this.sample);\n\n // if we have received custom data from the setCustomDataOnce API call, we need to set\n // them as \"the last one\" (we need to override normal customData and SSAI custom data)\n if (customDataOnceValues != null) {\n this.changeCustomData(customDataOnceValues);\n }\n\n // Initial quality info should be available for the first sample after setup, so if there is no quality info yet, we try to set it *before* sending a sample.\n // In the general case, a qualitychange event first triggers a sample of the state we were in before the qualitychange sample itself is sent.\n // So to only report quality updates on the qualitychange sample and not the ones before it, we need to update the quality info *after* sending a sample,\n // making it available for future samples (e.g. qualitychange sample).\n // We only check videoBitrate and not audioBitrate since the latter is often reported as null/0 anyways.\n if (isNullish(this.sample.videoBitrate) || this.sample.videoBitrate <= 0) {\n setQualityInfoOnSample(this.sample, this.adapter.getCurrentPlaybackInfo());\n const copySample = {...this.sample};\n this.backend.sendRequest(copySample);\n } else {\n const copySample = {...this.sample};\n this.backend.sendRequest(copySample);\n setQualityInfoOnSample(this.sample, this.adapter.getCurrentPlaybackInfo());\n }\n\n // clear sample state values after sending a sample\n clearSampleStateValues(this.sample);\n }\n\n sendSsaiEngagementAdSample(data: SsaiEngagementInteractionData) {\n if (this.config.config?.ssaiEngagementTrackingEnabled !== true) {\n // if not enabled in config, do not send SSAI engagement AdSample\n return;\n }\n\n if (isSsaiEngagementStartedData(data)) {\n const ssaiAdSample = createStartedAdSample(this.sample, data);\n\n this.backend.sendAdRequest(ssaiAdSample);\n return;\n }\n\n if (isSsaiEngagementQuartileData(data)) {\n const ssaiAdSample = createQuartileAdSample(this.sample, data);\n\n this.backend.sendAdRequest(ssaiAdSample);\n return;\n }\n\n if (isSsaiEngagementErrorData(data)) {\n data.analyticsError = this.transformError(data.analyticsError, data.originalError);\n\n const ssaiErrorAdSample = createErrorAdSample(this.sample, data);\n\n this.backend.sendAdRequest(ssaiErrorAdSample);\n return;\n }\n }\n\n /**\n * This method sanitizes the input and updates the analytics config.\n * @param values Object containing the customData and other fields\n */\n private changeCustomData = (values: CustomDataValues) => {\n this.config = {\n ...this.config,\n ...extractCustomDataFieldsOnly(values),\n };\n this.setConfigParameters();\n this.setAutoDetectedDeviceInformation();\n };\n\n private setCompletionValues() {\n if (this.adapter.videoCompletionTracker) {\n const completed = this.adapter.videoCompletionTracker.addWatched({\n start: this.sample.videoTimeStart,\n end: this.sample.videoTimeEnd,\n } as Timespan);\n const completedTotal = this.adapter.videoCompletionTracker.getCompletionPercentage();\n\n if (!Number.isNaN(completed) && !Number.isNaN(completedTotal)) {\n this.sample.completed = completed;\n this.sample.completedTotal = completedTotal;\n }\n }\n }\n\n private setVideoTimeStart(value: number | undefined) {\n this.sample.videoTimeStart = value;\n }\n\n private setVideoTimeEnd(value: number | undefined) {\n this.sample.videoTimeEnd = value;\n }\n\n transformError(error: AnalyticsError, originalError: any): AnalyticsError {\n const analyticsError = {\n code: error.code,\n message: error.message,\n severity: error.severity,\n };\n\n try {\n const transformedError = this.config.config?.errorTransformerCallback?.transform(analyticsError, {\n originalError: originalError,\n });\n\n analyticsError.code = isNumber(transformedError?.code) ? transformedError?.code : analyticsError.code;\n analyticsError.message = isValidString(transformedError?.message)\n ? transformedError?.message\n : analyticsError.message;\n analyticsError.severity =\n isValidString(transformedError?.severity) && isErrorSeverity(transformedError?.severity)\n ? transformedError!.severity\n : analyticsError.severity;\n } catch (error) {\n logger.error('Error in errorTransformerCallback', error);\n }\n\n return analyticsError;\n }\n\n private buildInitialSample(): Sample {\n const player = this.config.player || this.adapter.getPlayerName();\n const screenDimensions = getGlobalScreenDimensions();\n\n return {\n ad: 0,\n analyticsVersion: VERSION,\n audioBitrate: 0,\n buffered: 0,\n completedTotal: 0,\n droppedFrames: 0,\n duration: 0,\n isLive: this.config.isLive ?? false,\n language: getGlobalNavigatorLanguage(),\n pageLoadTime: 0,\n pageLoadType: Utils.getPageLoadType(),\n path: getDefaultSamplePath(),\n paused: 0,\n platform: 'web',\n played: 0,\n player,\n playerStartupTime: 0,\n playerTech: this.adapter.getPlayerTech(),\n screenHeight: screenDimensions?.height,\n screenWidth: screenDimensions?.width,\n seeked: 0,\n size: PlayerSize.Window,\n startupTime: 0,\n time: 0,\n userAgent: getGlobalNavigatorUserAgent(),\n version: player + '-' + this.adapter.getPlayerVersion(),\n videoBitrate: 0,\n videoDuration: 0,\n videoPlaybackHeight: 0,\n videoPlaybackWidth: 0,\n videoStartupTime: 0,\n videoTimeEnd: 0,\n videoTimeStart: 0,\n videoWindowHeight: 0,\n videoWindowWidth: 0,\n };\n }\n\n static create(config: AnalyticsConfig, adapter: InternalAdapterAPI): Analytics {\n const backendFactory: BackendFactory = new BackendFactory();\n const sessionHandler: SessionPersistenceHandler = new SessionPersistenceHandler(config);\n const featureManager = new FeatureManager<FeatureConfigContainer>();\n const onErrorDetailEventDispatcher = new EventDispatcher<OnErrorDetailEventObject>();\n const identicalErrorReportingLimiter = new IdenticalErrorReportingLimiter();\n return new Analytics(\n config,\n adapter,\n backendFactory,\n sessionHandler,\n featureManager,\n onErrorDetailEventDispatcher,\n identicalErrorReportingLimiter,\n );\n }\n}\n\n// We separate the quality info from `setPlaybackInfoFromAdapter` to be able to explicitly set/update the quality info only when it changes.\nexport function setQualityInfoOnSample(sample: Sample, playbackInfo: PlaybackInfo) {\n if (isNumber(playbackInfo.videoPlaybackHeight)) {\n sample.videoPlaybackHeight = playbackInfo.videoPlaybackHeight;\n }\n if (isNumber(playbackInfo.videoPlaybackWidth)) {\n sample.videoPlaybackWidth = playbackInfo.videoPlaybackWidth;\n }\n if (isNumber(playbackInfo.videoBitrate)) {\n sample.videoBitrate = playbackInfo.videoBitrate;\n }\n if (isNumber(playbackInfo.audioBitrate)) {\n sample.audioBitrate = playbackInfo.audioBitrate;\n }\n}\n","import {DeferredLicenseLoadingAdapterAPI} from '../adapters/internal/DeferredLicenseLoadingAdapterAPI';\nimport {AnalyticsConfig, CollectorConfig} from '../types/AnalyticsConfig';\nimport {AuthenticationCallback} from '../types/AuthenticationCallback';\nimport {LicensingRequest} from '../types/LicensingRequest';\nimport {LicenseCall} from '../utils/LicenseCall';\nimport {ANALYTICS_BACKEND_BASE_URL} from '../utils/Settings';\n\nimport {Backend} from './Backend';\nimport {DebuggingBackend} from './DebuggingBackend';\nimport {LicenseCheckingBackend} from './LicenseCheckingBackend';\nimport {LongPlaytimeFilteringBackend} from './LongPlaytimeFilteringBackend';\nimport {NoOpBackend} from './NoOpBackend';\nimport {SequenceNumberBackend} from './SequenceNumberBackend';\n\nexport interface InternalCollectorConfig extends CollectorConfig {\n /**\n * Internal \"hidden\" collector config property.\n *\n * It is used only by the Bitmovin Player Testautomation Suite to insert \"AssertionBackend\" and to be able to intercept\n * all backend requests, thus enabling to test and verify of those requests.\n *\n * @see https://github.com/bitmovin-engineering/player-testing/blob/develop/lib/bitdashPlayerTest/analytics/AnalyticsAssertionBackend.ts\n */\n wrapBackend: (innerBackend: Backend) => Backend;\n}\n\nexport class BackendFactory {\n createBackend(\n analyticsConfig: AnalyticsConfig,\n licensingRequest: LicensingRequest,\n adapter: DeferredLicenseLoadingAdapterAPI,\n authenticationCallback: AuthenticationCallback,\n ): Backend {\n if (!this.isEnabled(analyticsConfig)) {\n return new NoOpBackend();\n }\n const inner = this.createInnerBackend(analyticsConfig, licensingRequest, adapter, authenticationCallback);\n return this.decorateWithDebuggingBackend(analyticsConfig, inner);\n }\n\n private decorateWithDebuggingBackend(config: AnalyticsConfig, backend: Backend): Backend {\n if (config.debug) {\n return new DebuggingBackend(config, backend);\n }\n return backend;\n }\n\n private decorateWithBackendFromConfigIfAvailable(analyticsConfig: AnalyticsConfig, innerBackend: Backend): Backend {\n if (\n analyticsConfig !== undefined &&\n analyticsConfig.config !== undefined &&\n (analyticsConfig.config as InternalCollectorConfig).wrapBackend !== undefined\n ) {\n return (analyticsConfig.config as InternalCollectorConfig).wrapBackend(innerBackend);\n }\n\n return innerBackend;\n }\n\n private isEnabled(analyticsConfig: AnalyticsConfig): boolean {\n return analyticsConfig.config === undefined || analyticsConfig.config.enabled !== false;\n }\n\n private createInnerBackend(\n analyticsConfig: AnalyticsConfig,\n licensingRequest: LicensingRequest,\n adapter: DeferredLicenseLoadingAdapterAPI,\n authenticationCallback: AuthenticationCallback,\n ): Backend {\n const backendUrl = (analyticsConfig.config && analyticsConfig.config.backendUrl) || ANALYTICS_BACKEND_BASE_URL;\n let innerBackend: Backend = new LicenseCheckingBackend(\n licensingRequest,\n LicenseCall,\n backendUrl,\n adapter,\n authenticationCallback,\n );\n innerBackend = this.decorateWithBackendFromConfigIfAvailable(analyticsConfig, innerBackend);\n\n const sequenceNumberAssigningBackend = new SequenceNumberBackend(innerBackend);\n return new LongPlaytimeFilteringBackend(sequenceNumberAssigningBackend);\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {AnalyticsConfig, AnalyticsDebugConfig} from '../types/AnalyticsConfig';\nimport type {Sample} from '../types/Sample';\nimport {logger} from '../utils/Logger';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `DebuggingBackend` is responsible for printing debugging information\n * before forwarding the requests to the specified underlying backend.\n *\n * This allows for inspection of specific fields in the sample data before it is sent.\n * The fields can be specified through the {@link AnalyticsDebugConfig#fields}.\n *\n * @implements {Backend}\n * */\nexport class DebuggingBackend implements Backend {\n private readonly underlying: Backend;\n private readonly debugFields: string[] | undefined;\n\n constructor(config: AnalyticsConfig, underlying: Backend) {\n this.underlying = underlying;\n if (config.debug && (config.debug as AnalyticsDebugConfig).fields) {\n this.debugFields = (config.debug as AnalyticsDebugConfig).fields;\n }\n }\n\n sendRequest(sample: Sample): void {\n this.printFields(sample);\n this.underlying.sendRequest(sample);\n }\n\n sendUnloadRequest(sample: Sample): void {\n this.printFields(sample);\n this.underlying.sendUnloadRequest(sample);\n }\n\n sendAdRequest(adSample: AdSample): void {\n this.underlying.sendAdRequest(adSample);\n }\n\n private printFields(sample: Sample) {\n if (this.debugFields && this.debugFields.length) {\n const fields = {};\n this.debugFields.forEach((f) => (fields[f] = sample[f]));\n logger.table([fields]);\n }\n }\n}\n","export interface Subscribable<TArgs> {\n subscribe(callback: EventHandler<TArgs>): () => void;\n unsubscribe(callback: EventHandler<TArgs>);\n}\n\ntype EventHandler<TArgs> = (args: TArgs) => void;\n\nexport class EventDispatcher<TArgs> implements Subscribable<TArgs> {\n private callbacks: Array<EventHandler<TArgs>> = [];\n\n subscribe(callback: EventHandler<TArgs>): () => void {\n this.callbacks.push(callback);\n\n return () => this.unsubscribe(callback);\n }\n\n dispatch(args: TArgs) {\n const callbacks = this.callbacks.slice(0);\n callbacks.forEach((callback) => {\n callback(args);\n });\n }\n\n unsubscribe(callback: EventHandler<TArgs>) {\n const index = this.callbacks.indexOf(callback);\n if (index > -1) {\n this.callbacks.splice(index, 1);\n }\n }\n\n get subscriberCount() {\n return this.callbacks.length;\n }\n}\n","export const DEFAULT_HEARTBEAT_INTERVAL_MS = 59700;\n\nexport interface HeartbeatListener {\n /**\n * @param playerCurrentTime the current player playback time of the video in seconds.\n */\n onHeartbeat: (playerCurrentTime: number) => void;\n}\n\n/** Get the current player playback time of the video in seconds. */\ntype PlayerCurrentTimeCallback = () => number;\n\nexport class HeartbeatService {\n private heartbeatInterval: ReturnType<typeof setInterval> | undefined;\n private listener: HeartbeatListener | undefined;\n private readonly getPlayerCurrentTime: PlayerCurrentTimeCallback;\n\n constructor(getPlayerCurrentTime: PlayerCurrentTimeCallback) {\n this.getPlayerCurrentTime = getPlayerCurrentTime;\n }\n\n setListener(listener: HeartbeatListener) {\n this.listener = listener;\n }\n\n startHeartbeat() {\n if (this.heartbeatInterval !== undefined) {\n this.clearHeartbeat();\n }\n this.heartbeatInterval = setInterval(() => {\n this.listener?.onHeartbeat(this.getPlayerCurrentTime());\n }, DEFAULT_HEARTBEAT_INTERVAL_MS);\n }\n\n stopHeartbeat() {\n this.clearHeartbeat();\n }\n\n private clearHeartbeat() {\n clearTimeout(this.heartbeatInterval);\n this.heartbeatInterval = undefined;\n }\n}\n","import {ErrorSeverity} from '../types/AnalyticsConfig';\n\n/**\n * This class is used to limit error reporting for identical consecutive error codes and severities per session.\n *\n * Repeated consecutive errors of the same code and severity are limited to {@link IdenticalErrorReportingLimiter.MAX_IDENTICAL_ERROR_REPORTING}.\n */\nexport class IdenticalErrorReportingLimiter {\n /** The maximum number of times the same error code and severity can be reported consecutively. */\n private static MAX_IDENTICAL_ERROR_REPORTING = 5;\n\n private _lastErrorCode: number | undefined;\n private _lastErrorSeverity: ErrorSeverity | undefined;\n private _currentErrorCount = 0;\n\n /**\n * Determines whether an error with the given errorCode and errorSeverity should be reported,\n * based on the limit of identical consecutive error reports.\n *\n * @param errorCode - The error code for which we are checking the reporting conditions.\n * @param errorSeverity - The error severity for which we are checking the reporting conditions.\n * @returns {boolean} - Returns true if the error can be reported, false if it exceeds the limits.\n */\n shouldReportError(errorCode: number, errorSeverity: ErrorSeverity): boolean {\n if (errorCode === this._lastErrorCode && errorSeverity === this._lastErrorSeverity) {\n this._currentErrorCount++;\n return this._currentErrorCount <= IdenticalErrorReportingLimiter.MAX_IDENTICAL_ERROR_REPORTING;\n }\n\n this._lastErrorCode = errorCode;\n this._lastErrorSeverity = errorSeverity;\n this._currentErrorCount = 1;\n return true;\n }\n\n reset() {\n this._lastErrorCode = undefined;\n this._lastErrorSeverity = undefined;\n this._currentErrorCount = 0;\n }\n}\n","import type {DeferredLicenseLoadingAdapterAPI} from '../adapters/internal/DeferredLicenseLoadingAdapterAPI';\nimport type {AdSample} from '../types/AdSample';\nimport type {AuthenticationCallback} from '../types/AuthenticationCallback';\nimport {LicenseCallFunc, LicensingRequest, LicensingResponse, LicensingResult} from '../types/LicensingRequest';\nimport type {Sample} from '../types/Sample';\nimport {logger} from '../utils/Logger';\nimport {ANALYTICS_LICENSECALL_TIMEOUT} from '../utils/Settings';\n\nimport type {Backend} from './Backend';\nimport {NoOpBackend} from './NoOpBackend';\nimport {QueueBackend} from './QueueBackend';\nimport {RemoteBackend} from './RemoteBackend';\n\n/**\n * The `LicenseCheckingBackend` class is responsible for sending license requests\n * and routing samples to the appropriate backend based on the license status.\n *\n * The class manages a queue of samples during the license check process, ensuring that\n * samples are not lost while the license status is being determined. Once the license\n * is validated, the queued samples are flushed to the appropriate backend.\n *\n * @implements {Backend}\n */\nexport class LicenseCheckingBackend implements Backend {\n promise?: Promise<LicensingResponse>;\n private licenseLazyLoadingTimeoutHandle?: ReturnType<typeof setTimeout>;\n private backend: Backend;\n private info: LicensingRequest;\n\n constructor(\n info: LicensingRequest,\n private licenseCall: LicenseCallFunc,\n private backendBaseUrl: string,\n private adapter: DeferredLicenseLoadingAdapterAPI,\n private authenticationCallback: AuthenticationCallback,\n ) {\n this.info = {...info};\n this.backend = new QueueBackend();\n this.licenseCall = licenseCall;\n\n if (info.key !== undefined && info.key !== '') {\n this.promise = this.wrapLicenseCheckPromiseWithCallback(this.performLicenseCheck(), this.authenticationCallback);\n } else if (adapter.supportsDeferredLicenseLoading === true) {\n adapter.onLicenseKeyReceived.subscribe(this.licenseKeyReceived);\n adapter.onLicenseCallFailed.subscribe(this.licenseCallFailed);\n this.licenseLazyLoadingTimeoutHandle = setTimeout(this.licenseLazyLoadingTimeout, ANALYTICS_LICENSECALL_TIMEOUT);\n } else {\n authenticationCallback.authenticationCompleted(false, undefined);\n this.backend = new NoOpBackend();\n }\n }\n\n performLicenseCheck(): Promise<LicensingResponse> {\n const {key, domain, version} = this.info;\n if (!key || key === '') {\n const error: LicensingResponse = {\n status: LicensingResult.Denied,\n message: 'No license key provided',\n };\n this.backend = new NoOpBackend();\n return Promise.resolve(error);\n }\n\n return this.licenseCall(key, domain, version, this.backendBaseUrl)\n .then((result) => {\n if (result.status === LicensingResult.Granted) {\n const remoteBackend = new RemoteBackend(this.backendBaseUrl, key);\n (this.backend as QueueBackend).flushTo(remoteBackend);\n this.backend = remoteBackend;\n } else {\n throw new Error(result.message);\n }\n return result;\n })\n .catch((err: Error) => {\n if (err.message === 'Ignoring Impression due to DNT Header being set') {\n logger.error('License Check for Bitmovin Analytics failed because of', err);\n } else {\n logger.errorMessageToUser('License Check for Bitmovin Analytics failed because of', err);\n }\n this.backend = new NoOpBackend();\n return {\n status: LicensingResult.Denied,\n message: err.message,\n };\n });\n }\n\n sendRequest(sample: Sample): void {\n this.backend.sendRequest(sample);\n }\n sendUnloadRequest(sample: Sample): void {\n this.backend.sendUnloadRequest(sample);\n }\n sendAdRequest(adSample: AdSample): void {\n this.backend.sendAdRequest(adSample);\n }\n\n private licenseKeyReceived = (eventArgs: {licenseKey: string}) => {\n clearTimeout(this.licenseLazyLoadingTimeoutHandle);\n this.unsubscribeFromAdapter();\n this.info.key = eventArgs.licenseKey;\n this.promise = this.wrapLicenseCheckPromiseWithCallback(this.performLicenseCheck(), this.authenticationCallback);\n };\n\n private licenseCallFailed = () => {\n clearTimeout(this.licenseLazyLoadingTimeoutHandle);\n this.unsubscribeFromAdapter();\n this.backend = new NoOpBackend();\n this.authenticationCallback.authenticationCompleted(false, undefined);\n };\n\n private licenseLazyLoadingTimeout = () => {\n this.unsubscribeFromAdapter();\n this.backend = new NoOpBackend();\n this.authenticationCallback.authenticationCompleted(false, undefined);\n };\n\n private unsubscribeFromAdapter() {\n this.adapter.onLicenseKeyReceived.unsubscribe(this.licenseKeyReceived);\n this.adapter.onLicenseCallFailed.unsubscribe(this.licenseCallFailed);\n }\n\n private wrapLicenseCheckPromiseWithCallback(\n promise: Promise<LicensingResponse>,\n authenticationCallback: AuthenticationCallback,\n ): Promise<LicensingResponse> {\n return promise.then((response) => {\n authenticationCallback.authenticationCompleted(response.status === LicensingResult.Granted, response.features);\n return response;\n });\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\nimport {isNullish} from '../utils/Utils';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `LongPlaytimeFilteringBackend` is a decorator class that filters out samples\n * where the `played` time exceeds a specified threshold.\n *\n * If a sample's `played` time surpasses the threshold, it is not forwarded to the next backend.\n * Otherwise, the sample is passed along to the next backend for further processing.\n *\n * @implements {Backend}\n */\nexport class LongPlaytimeFilteringBackend implements Backend {\n readonly nextBackend: Backend;\n\n constructor(next: Backend) {\n this.nextBackend = next;\n }\n\n sendRequest(sample: Sample): void {\n if (this.isPlayedAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendRequest(sample);\n }\n\n sendUnloadRequest(sample: Sample): void {\n if (this.isPlayedAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendUnloadRequest(sample);\n }\n\n sendAdRequest(adSample: AdSample): void {\n this.nextBackend.sendAdRequest(adSample);\n }\n\n private isPlayedAboveThreshold(sample: Sample): boolean {\n return (isNullish(sample.played) ? 0 : sample.played) >= 90000;\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `NoOpBackend` is a no-operation implementation of the `Backend` interface.\n * It serves as a placeholder backend when the actual `Backend` functionality is disabled or not required.\n * E.g. in scenarios such as releasing the adapter or when the Collector is disabled via {@link CollectorConfig#enabled}.\n *\n * Using `NoOpBackend` ensures that the code does not need to handle cases where `Backend` might be undefined,\n * thereby simplifying the logic and reducing the need for null or undefined checks.\n *\n * @implements {Backend}\n */\nexport class NoOpBackend implements Backend {\n sendRequest(_sample: Sample): void {\n // empty\n }\n sendUnloadRequest(_sample: Sample): void {\n // empty\n }\n sendAdRequest(_adSample: AdSample): void {\n throw new Error('Method not implemented.');\n }\n}\n","import {isFiniteNumber} from '../utils/numberUtils';\nimport * as Settings from '../utils/Settings';\n\nconst INITIAL_VALUE = 0;\n\n/**\n * This service is responsible for deciding whether a quality change event should be sent or not, based on\n * - the quality changes count that has already been sent in a certain timeframe/interval\n * - the previous video and audio bitrate values, to avoid sending the first quality change event or the following\n * events when the bitrate did not change (some players report quality changes with the same bitrate, which should\n * not be tracked)\n * - whether the startup has finished, to avoid sending quality change events for the initial bitrate values\n * that some players report before startup, which can differ from the ones that are used after startup\n */\nexport default class QualityChangeService {\n /** Flag to block quality change events when a certain threshold in a certain timeframe/interval is exceeded */\n private qualityChangeCount = INITIAL_VALUE;\n private qualityChangeCountResetIntervalId: ReturnType<typeof setInterval> | undefined;\n private readonly QUALITY_CHANGE_COUNT_THRESHOLD: number;\n\n /** Flag to block the first (initial) video quality change event or the following events when the bitrate did not change */\n private previousVideoBitrate = INITIAL_VALUE;\n /** Flag to block the first (initial) audio quality change event or the following events when the bitrate did not change */\n private previousAudioBitrate = INITIAL_VALUE;\n\n /** Flag to block quality change events until startup has finished */\n private startupHasFinished = false;\n\n constructor(qualityChangeCountThreshold: number = Settings.ANALYTICS_QUALITY_CHANGE_COUNT_THRESHOLD) {\n this.QUALITY_CHANGE_COUNT_THRESHOLD = qualityChangeCountThreshold;\n }\n\n resetValues() {\n this.qualityChangeCount = INITIAL_VALUE;\n this.stopResetInterval();\n\n this.previousVideoBitrate = INITIAL_VALUE;\n this.previousAudioBitrate = INITIAL_VALUE;\n\n this.startupHasFinished = false;\n }\n\n increaseCounter() {\n this.qualityChangeCount++;\n }\n\n hasExceededQualityChangeThreshold(): boolean {\n return this.qualityChangeCount > this.QUALITY_CHANGE_COUNT_THRESHOLD;\n }\n\n setStartupHasFinished(startupVideoBitrate: number | undefined, startupAudioBitrate: number | undefined): void {\n this.startupHasFinished = true;\n\n // check if the startup video bitrate value is known/defined and valid\n if (isFiniteNumber(startupVideoBitrate)) {\n this.previousVideoBitrate = startupVideoBitrate;\n }\n // check if the startup audio bitrate value is known/defined and valid\n if (isFiniteNumber(startupAudioBitrate)) {\n this.previousAudioBitrate = startupAudioBitrate;\n }\n }\n\n shouldAllowVideoQualityChange(newBitrate: number | undefined): boolean {\n return (\n // if the startup has finished\n this.startupHasFinished &&\n // if the new bitrate value is valid\n isFiniteNumber(newBitrate) &&\n // if the new bitrate is not the first one reported (the initial value is not still set)\n this.previousVideoBitrate !== INITIAL_VALUE &&\n // if the bitrate did change\n this.previousVideoBitrate !== newBitrate &&\n // if the quality change count threshold has not been exceeded\n !this.hasExceededQualityChangeThreshold()\n );\n }\n\n setVideoBitrate(newBitrate: number): void {\n if (this.startupHasFinished) {\n this.previousVideoBitrate = newBitrate;\n }\n }\n\n shouldAllowAudioQualityChange(newBitrate: number | undefined): boolean {\n return (\n // if the startup has finished\n this.startupHasFinished &&\n // if the new bitrate value is valid\n isFiniteNumber(newBitrate) &&\n // if the new bitrate is not the first one reported (the initial value is not still set)\n this.previousAudioBitrate !== INITIAL_VALUE &&\n // if the bitrate did change\n this.previousAudioBitrate !== newBitrate &&\n // if the quality change count threshold has not been exceeded\n !this.hasExceededQualityChangeThreshold()\n );\n }\n\n setAudioBitrate(newBitrate: number): void {\n if (this.startupHasFinished) {\n this.previousAudioBitrate = newBitrate;\n }\n }\n\n startResetInterval() {\n if (this.qualityChangeCountResetIntervalId !== undefined) {\n return;\n }\n\n this.qualityChangeCountResetIntervalId = setInterval(() => {\n this.qualityChangeCount = 0;\n }, Settings.ANALYTICS_QUALITY_CHANGE_COUNT_RESET_INTERVAL);\n }\n\n stopResetInterval() {\n if (this.qualityChangeCountResetIntervalId === undefined) {\n return;\n }\n\n clearInterval(this.qualityChangeCountResetIntervalId);\n delete this.qualityChangeCountResetIntervalId;\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `QueueBackend` class is responsible for queuing samples for deferred processing.\n * Samples are stored in different queues depending on the sample type and can be flushed\n * to another backend for further processing.\n *\n * This is useful e.g. to still collect sample data while waiting for a license call to succeed.\n *\n * @implements {Backend}\n */\nexport class QueueBackend implements Backend {\n private readonly queue: Sample[] = [];\n private readonly unloadQueue: Sample[] = [];\n private readonly adQueue: AdSample[] = [];\n\n sendRequest(sample: Sample): void {\n this.queue.push(sample);\n }\n sendUnloadRequest(sample: Sample): void {\n this.unloadQueue.push(sample);\n }\n sendAdRequest(adSample: AdSample): void {\n this.adQueue.push(adSample);\n }\n\n flushTo(backend: Backend) {\n this.queue.forEach((e) => {\n backend.sendRequest(e);\n });\n this.unloadQueue.forEach((e) => {\n backend.sendUnloadRequest(e);\n });\n this.adQueue.forEach((e) => {\n backend.sendAdRequest(e);\n });\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\nimport {AnalyticsCall} from '../utils/AnalyticsCall';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `RemoteBackend` class is responsible for actually sending out the samples using the {@link AnalyticsCall} class.\n * Before each sample is sent, the `RemoteBackend` attaches a license key to the sample.\n *\n * @implements {Backend}\n */\nexport class RemoteBackend implements Backend {\n private readonly analyticsCall: AnalyticsCall;\n private readonly licenseKey: string;\n\n constructor(backendBaseUrl: string, licenseKey: string) {\n this.analyticsCall = new AnalyticsCall(backendBaseUrl);\n this.licenseKey = licenseKey;\n }\n\n sendRequest(sample: Sample): void {\n sample.key = this.licenseKey;\n this.analyticsCall.sendRequest(sample);\n }\n\n sendUnloadRequest(sample: Sample): void {\n sample.key = this.licenseKey;\n this.analyticsCall.sendUnloadRequest(sample);\n }\n\n sendAdRequest(adSample: AdSample): void {\n adSample.key = this.licenseKey;\n this.analyticsCall.sendAdRequest(adSample);\n }\n}\n","import type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\nimport {SEQUENCE_NUMBER_LIMIT} from '../utils/Settings';\n\nimport type {Backend} from './Backend';\n\n/**\n * The `SequenceNumberBackend` is a decorator class that increments a samples sequence number and filters out samples\n * where the `sequenceNumber` exceeds a specified threshold.\n *\n * If a sample's `sequenceNumber` surpasses the threshold, it is not forwarded to the next backend.\n * Otherwise, the sample is passed along to the next backend for further processing.\n *\n * @implements {Backend}\n */\nexport class SequenceNumberBackend implements Backend {\n readonly nextBackend: Backend;\n sequenceNumber = 0;\n\n constructor(underlying: Backend) {\n this.nextBackend = underlying;\n }\n\n sendRequest(sample: Sample): void {\n this.updateSampleBeforeSending(sample);\n if (this.isSequenceNumberAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendRequest(sample);\n }\n\n sendUnloadRequest(sample: Sample): void {\n this.updateSampleBeforeSending(sample);\n if (this.isSequenceNumberAboveThreshold(sample)) {\n return;\n }\n this.nextBackend.sendUnloadRequest(sample);\n }\n\n sendAdRequest(adSample: AdSample): void {\n if (this.isSequenceNumberAboveThreshold(adSample)) {\n return;\n }\n this.nextBackend.sendAdRequest(adSample);\n }\n\n private updateSampleBeforeSending(sample: Sample) {\n sample.sequenceNumber = this.sequenceNumber++;\n }\n\n private isSequenceNumberAboveThreshold(sample: Sample): boolean {\n return (sample.sequenceNumber ?? 0) > SEQUENCE_NUMBER_LIMIT;\n }\n}\n","import type {AnalyticsConfig} from '../types/AnalyticsConfig';\nimport {deleteCookie, getCookie, setCookie} from '../utils/documentUtils';\nimport {isNumber} from '../utils/numberUtils';\nimport {isBlank, isValidString} from '../utils/stringUtils';\nimport {isNotNullish, isNullish} from '../utils/Utils';\nimport {generateUUID} from '../utils/uuidUtils';\n\nexport const COOKIE_NAME_BITMOVIN_ANALYTICS_UUID = 'bitmovin_analytics_uuid';\n/** One year in seconds */\nexport const COOKIE_DEFAULT_MAX_AGE = 365 * 24 * 60 * 60;\n\nexport class SessionPersistenceHandler {\n readonly userId: string;\n\n constructor(config: AnalyticsConfig) {\n const collectorConfig = config.config;\n\n const shouldNotUseCookies = collectorConfig?.cookiesEnabled === false;\n\n if (shouldNotUseCookies) {\n deleteCookie(COOKIE_NAME_BITMOVIN_ANALYTICS_UUID);\n this.userId = generateUUID();\n return;\n }\n\n const existingUserId = getCookie(COOKIE_NAME_BITMOVIN_ANALYTICS_UUID);\n this.userId = isNotNullish(existingUserId) && !isBlank(existingUserId) ? existingUserId : generateUUID();\n\n const cookieDomain = validateCookieDomainValue(collectorConfig?.cookiesDomain);\n const cookieMaxAge = validateCookieMaxAgeValue(collectorConfig?.cookiesMaxAge);\n\n // we set also expires, because max-age is not supported on old browsers like IE8\n const nowMillis = Date.now();\n const expirationDate = new Date(nowMillis + cookieMaxAge * 1000);\n const cookieExpires = expirationDate.toUTCString();\n\n setCookie(COOKIE_NAME_BITMOVIN_ANALYTICS_UUID, this.userId, {\n domain: cookieDomain,\n expires: cookieExpires,\n maxAge: cookieMaxAge,\n });\n }\n}\n\nexport const validateCookieDomainValue = (value: unknown): string | undefined => {\n if (isNullish(value)) {\n return undefined;\n }\n\n if (!isValidString(value)) {\n return undefined;\n }\n\n if (isBlank(value)) {\n return undefined;\n }\n\n return encodeURIComponent(value);\n};\n\nexport const validateCookieMaxAgeValue = (value: unknown): number => {\n if (isNullish(value)) {\n return COOKIE_DEFAULT_MAX_AGE;\n }\n\n if (!isNumber(value)) {\n return COOKIE_DEFAULT_MAX_AGE;\n }\n\n return value;\n};\n","import type {CodecInfo} from '../types/CodecInfo';\nimport type {PlaybackInfo} from '../types/PlaybackInfo';\nimport {isBlank} from '../utils/stringUtils';\nimport {isNotNullish} from '../utils/Utils';\n\n/**\n * This class is used to store source specific information for the player\n * mainly as a fallback if sourceInfo cannot be determined by the player since the source is already unloaded\n */\nexport class SourceInfoFallbackService {\n private streamFormat: PlaybackInfo['streamFormat'];\n private audioCodec: PlaybackInfo['audioCodec'];\n private videoCodec: PlaybackInfo['videoCodec'];\n\n reset() {\n this.streamFormat = undefined;\n this.audioCodec = undefined;\n this.videoCodec = undefined;\n }\n\n setStreamFormat(streamFormat: PlaybackInfo['streamFormat']) {\n this.streamFormat = streamFormat;\n }\n\n applyStreamFormat(playbackInfo: PlaybackInfo) {\n if (isBlank(this.streamFormat)) {\n return;\n }\n playbackInfo.streamFormat = this.streamFormat;\n }\n\n /**\n * Apply fallback values to {@link PlaybackInfo} if available.\n * If provided {@link CodecInfo} values are available, we store them as new fallback values, before we apply them.\n */\n applyAndStoreCodecInfo(playbackInfo: PlaybackInfo, codecInfo: CodecInfo | undefined) {\n if (isNotNullish(codecInfo?.audioCodec)) {\n this.audioCodec = codecInfo.audioCodec;\n }\n if (isNotNullish(codecInfo?.videoCodec)) {\n this.videoCodec = codecInfo.videoCodec;\n }\n\n if (!isBlank(this.audioCodec)) {\n playbackInfo.audioCodec = this.audioCodec;\n }\n if (!isBlank(this.videoCodec)) {\n playbackInfo.videoCodec = this.videoCodec;\n }\n }\n}\n","import type {SsaiAdBreakMetadata, SsaiAdMetadata, SsaiAdQuartile, SsaiAdQuartileMetadata} from '../../api/AdapterAPI';\nimport {AD_TYPE} from '../../enums/AdType';\nimport {ErrorCode} from '../../enums/ErrorCode';\nimport {AnalyticsError} from '../../types/AnalyticsConfig';\nimport {customDataValuesKeys} from '../../types/CustomDataValues';\nimport type {Sample} from '../../types/Sample';\nimport {isNotNullish} from '../../utils/Utils';\nimport {generateUUID} from '../../utils/uuidUtils';\n\nimport type {InternalSsaiMetadata, SsaiEngagementInteractionData} from './ssaiEngagementInteractionData';\nimport {\n getCurrentMonotonicTimestampInMs,\n getMonotonicTimestampInMsSince,\n SSAI_RELATED_SAMPLE_MARKER,\n} from './ssaiUtils';\n\nexport type SsaiEventHandler = {\n getPlayerCurrentTime: () => number;\n reportEngagementInteraction: (data: SsaiEngagementInteractionData) => void;\n reportPlaybackInteraction: (timestamp: number, playerCurrentTime: number) => void;\n};\n\nenum SsaiState {\n AD_BREAK_STARTED,\n ACTIVE,\n IDLE,\n}\n\n// we start with -1, to be able to increment it before sending the first sample\n// this way the current adIndex is the one of the current playing ad\nconst INITIAL_AD_INDEX_VALUE = -1;\n\nexport class SsaiService {\n /** if `undefined` then service is not active and should not do anything, why: initially we activate it only for Bitmovin8 */\n private eventHandler: SsaiEventHandler | undefined = undefined;\n\n /** Index of the current ad in the whole session */\n private adIndex: number = INITIAL_AD_INDEX_VALUE;\n\n private state: SsaiState = SsaiState.IDLE;\n private isFirstSampleOfAd = false;\n /**\n * represents the current playing ad metadata\n * is `undefined` when no ad is playing (after endAdBreak)\n * or omitted by customer\n */\n private currentAdMetadata: InternalSsaiMetadata | undefined;\n\n /**\n * The impression id for the currently playing ad\n * is undefined when no ad is playing\n */\n private currentAdImpressionId: string | undefined;\n\n /** List of quartiles already sent for the current ad */\n private sentAdQuartiles: SsaiAdQuartile[] = [];\n\n /**\n * Flags whether an error was sent during an ad to avoid sending multiple errors for one ad,\n * which would skew e.g. the ad abandonment rate.\n */\n private errorSent: boolean = false;\n\n /**\n * The timestamp marking when the `adStart` method was called.\n * This timestamp is used to calculate the time difference between the `adStart` call\n * and subsequent `adQuartileFinished` or `sendAdEngagementErrorSample` calls.\n */\n private timestampOfAdStart: number | undefined;\n\n activate(eventHandler: SsaiEventHandler) {\n this.eventHandler = eventHandler;\n }\n\n adBreakStart(adBreakMetadata?: SsaiAdBreakMetadata) {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state != SsaiState.IDLE) {\n return;\n }\n\n this.state = SsaiState.AD_BREAK_STARTED;\n this.currentAdMetadata = {\n ...adBreakMetadata,\n };\n }\n\n adStart(adMetadata?: SsaiAdMetadata) {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state == SsaiState.IDLE) {\n return;\n }\n\n const timestamp = new Date().getTime();\n const playerCurrentTime = this.eventHandler.getPlayerCurrentTime();\n\n // report playback sample - will be saved in our playback related data lake\n // - with the first adStart call we need to close the current normal playback sample (no ssai ad information yet because SsaiState is not yet set to active)\n // - with all following adStart calls, we will deliver previous ssai ad information (SsaiState is already set to active)\n this.eventHandler.reportPlaybackInteraction(timestamp, playerCurrentTime);\n\n this.state = SsaiState.ACTIVE;\n // to include the adIndex in the next sample which will be the first sample of this started ad\n this.isFirstSampleOfAd = true;\n this.adIndex++;\n\n this.resetAdData();\n\n this.currentAdMetadata = {\n adPosition: this.currentAdMetadata?.adPosition,\n adId: adMetadata?.adId,\n adSystem: adMetadata?.adSystem,\n customData: adMetadata?.customData,\n };\n\n this.currentAdImpressionId = generateUUID();\n this.timestampOfAdStart = getCurrentMonotonicTimestampInMs();\n\n // report engagement sample - will be saved in our ad related data lake\n this.eventHandler.reportEngagementInteraction({\n type: 'started',\n adIndex: this.adIndex,\n currentAdImpressionId: this.currentAdImpressionId,\n currentAdMetadata: isNotNullish(this.currentAdMetadata) ? this.currentAdMetadata : {},\n });\n }\n\n adQuartileFinished(adQuartile: SsaiAdQuartile, adQuartileMetadata: SsaiAdQuartileMetadata) {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not activated\n return;\n }\n\n if (this.state != SsaiState.ACTIVE) {\n return;\n }\n\n if (this.sentAdQuartiles.includes(adQuartile)) {\n //do nothing if adQuartile was already sent\n return;\n }\n\n this.eventHandler.reportEngagementInteraction({\n type: 'quartile',\n adIndex: this.adIndex,\n currentAdImpressionId: this.currentAdImpressionId!,\n currentAdMetadata: isNotNullish(this.currentAdMetadata) ? this.currentAdMetadata : {},\n quartile: adQuartile,\n quartileMetadata: adQuartileMetadata,\n timeSinceAdStartedInMs: getMonotonicTimestampInMsSince(this.timestampOfAdStart),\n });\n this.sentAdQuartiles.push(adQuartile);\n }\n\n adBreakEnd() {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state == SsaiState.IDLE) {\n return;\n }\n\n if (this.state == SsaiState.ACTIVE) {\n const timestamp = new Date().getTime();\n const playerCurrentTime = this.eventHandler.getPlayerCurrentTime();\n this.eventHandler.reportPlaybackInteraction(timestamp, playerCurrentTime);\n }\n\n this.resetAdBreakData();\n }\n\n manipulate(sample: Sample): void {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state != SsaiState.ACTIVE) {\n return;\n }\n\n sample.ad = AD_TYPE.SSAI;\n sample.adId = this.currentAdMetadata?.adId;\n sample.adSystem = this.currentAdMetadata?.adSystem;\n sample.adPosition = this.currentAdMetadata?.adPosition;\n // we only mark the first sample of an ssai ad with the index in the playback/audience data (non ad table)\n // this allows us to count the number of ads\n if (this.isFirstSampleOfAd) {\n sample.adIndex = this.adIndex;\n this.isFirstSampleOfAd = false;\n }\n\n const customData = this.currentAdMetadata?.customData;\n if (isNotNullish(customData)) {\n customDataValuesKeys.forEach((key) => {\n if (customData[key]) {\n sample[key] = customData[key];\n }\n });\n }\n\n sample[SSAI_RELATED_SAMPLE_MARKER] = true; // mark it as ssai sample\n }\n\n sendAdEngagementErrorSample(error: AnalyticsError, originalError: any) {\n if (!isActivated(this.eventHandler)) {\n // nothing to do if service is not active\n return;\n }\n\n if (this.state !== SsaiState.ACTIVE) {\n return;\n }\n\n // only send one error sample per ad\n if (this.errorSent) {\n return;\n }\n\n // This error code is related to the Analytics product and is non-fatal.\n // It is not triggered by the Player and does not interrupt or affect playback,\n // so there is no need to report an ad error sample.\n if (error.code === ErrorCode.QUALITY_CHANGE_THRESHOLD_EXCEEDED.code) {\n return;\n }\n\n this.eventHandler.reportEngagementInteraction({\n type: 'error',\n adIndex: this.adIndex,\n currentAdImpressionId: this.currentAdImpressionId!,\n currentAdMetadata: isNotNullish(this.currentAdMetadata) ? this.currentAdMetadata : {},\n analyticsError: error,\n originalError: originalError,\n timeSinceAdStartedInMs: getMonotonicTimestampInMsSince(this.timestampOfAdStart),\n });\n this.errorSent = true;\n }\n\n isInActiveState(): boolean {\n return this.state === SsaiState.ACTIVE;\n }\n\n resetSourceRelatedState() {\n this.resetAdBreakData();\n this.adIndex = INITIAL_AD_INDEX_VALUE;\n }\n\n private resetAdBreakData() {\n this.state = SsaiState.IDLE;\n this.isFirstSampleOfAd = false;\n delete this.currentAdMetadata;\n this.resetAdData();\n }\n\n private resetAdData() {\n delete this.currentAdMetadata?.customData;\n delete this.currentAdMetadata?.adId;\n delete this.currentAdMetadata?.adSystem;\n this.errorSent = false;\n this.currentAdImpressionId = undefined;\n this.sentAdQuartiles = [];\n this.timestampOfAdStart = undefined;\n }\n}\n\nfunction isActivated(eventHandler: SsaiEventHandler | undefined): eventHandler is SsaiEventHandler {\n return isNotNullish(eventHandler);\n}\n","import {SsaiAdBreakMetadata, SsaiAdMetadata, SsaiAdQuartile, SsaiAdQuartileMetadata} from '../../api/AdapterAPI';\nimport {AnalyticsError} from '../../types/AnalyticsConfig';\n\nexport type InternalSsaiMetadata = SsaiAdBreakMetadata & SsaiAdMetadata;\n\ntype SsaiEngagementBaseData = {\n adIndex: number;\n currentAdImpressionId: string;\n currentAdMetadata: InternalSsaiMetadata;\n type: 'error' | 'quartile' | 'started';\n};\n\nexport type SsaiEngagementErrorData = SsaiEngagementBaseData & {\n analyticsError: AnalyticsError;\n originalError?: any;\n timeSinceAdStartedInMs: number | undefined;\n type: 'error';\n};\n\nexport function isSsaiEngagementErrorData(data: SsaiEngagementInteractionData): data is SsaiEngagementErrorData {\n return data.type === 'error';\n}\n\nexport type SsaiEngagementQuartileData = SsaiEngagementBaseData & {\n quartile: SsaiAdQuartile;\n quartileMetadata: SsaiAdQuartileMetadata;\n timeSinceAdStartedInMs: number | undefined;\n type: 'quartile';\n};\n\nexport function isSsaiEngagementQuartileData(data: SsaiEngagementInteractionData): data is SsaiEngagementQuartileData {\n return data.type === 'quartile';\n}\n\nexport type SsaiEngagementStartedData = SsaiEngagementBaseData & {type: 'started'};\n\nexport function isSsaiEngagementStartedData(data: SsaiEngagementInteractionData): data is SsaiEngagementStartedData {\n return data.type === 'started';\n}\n\nexport type SsaiEngagementInteractionData =\n | SsaiEngagementErrorData\n | SsaiEngagementQuartileData\n | SsaiEngagementStartedData;\n","import type {SsaiAdQuartile, SsaiAdQuartileMetadata} from '../../api/AdapterAPI';\nimport type {AdSample} from '../../types/AdSample';\nimport {ErrorSeverity} from '../../types/AnalyticsConfig';\nimport {customDataValuesKeys} from '../../types/CustomDataValues';\nimport type {Sample} from '../../types/Sample';\nimport {getGlobalPerformanceNow} from '../../utils/globalScopeUtils';\nimport {isNotNullish, isNullish} from '../../utils/Utils';\n\nimport type {\n InternalSsaiMetadata,\n SsaiEngagementErrorData,\n SsaiEngagementQuartileData,\n SsaiEngagementStartedData,\n} from './ssaiEngagementInteractionData';\n\n/**\n * Ssai marker property for {@link Sample} to indicate that this is \"ssai related sample\" and can cause the spike\n * on ingress side. It will be picked up in `AnalyticsCall` and used to send that \"ssai related sample\" as request\n * with ssai redirection. @see {@link ROUTING_URL_PARAM}\n *\n * What is \"ssai related sample\" ?\n * - \"last sample\" that was triggered to be sent, because of coming SSAI interaction, the SSAI ad break start (WITHOUT `sample.ad = 2`),\n * because it causes also the spike as all viewers are received same SSAI at the same time.\n * - all following samples, triggered by SSAI interaction while SSAI ad break is running (now WITH `sample.ad = 2`)\n *\n * We don't we need it with {@link AdSample} too?\n * Because all \"ssai related ad samples\" are triggered only during ssai ad break, so all have already\n * {@link AdSample#adType} property set and we can relay on that in `AnalyticsCall` to send them with ssai redirection.\n */\nexport const SSAI_RELATED_SAMPLE_MARKER = 'triggeredBySsai';\n\nexport function isSsaiRelatedSample(sample: AdSample | Sample): boolean {\n if (sample[SSAI_RELATED_SAMPLE_MARKER]) {\n delete sample[SSAI_RELATED_SAMPLE_MARKER]; // clean up the marker property that should not be present on the sample property\n return true;\n } else if ((sample as AdSample).adType === 2) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Due to ssai being spiky by design, we should mark all analytics requests (with samples / ad samples)\n * that are ssai related, with a specific URL parameter. The load balancer can then route traffic according to the URL\n * parameter to a different ingress instance, which gives us more flexibility when ssai spikes are coming in.\n */\nexport const ROUTING_URL_PARAM = 'routingParam';\nexport const ROUTING_URL_PARAM_VALUE_SSAI = 'ssai';\n\nexport function appendSsaiRoutingParam(url: string): string {\n return `${url}?${ROUTING_URL_PARAM}=${ROUTING_URL_PARAM_VALUE_SSAI}`;\n}\n\nfunction createAdSampleFromSample(sample: Sample): AdSample {\n return {\n audioBitrate: sample?.audioBitrate,\n analyticsVersion: sample?.analyticsVersion,\n adPlaybackHeight: sample?.videoPlaybackHeight,\n adPlaybackWidth: sample?.videoPlaybackWidth,\n cdnProvider: sample?.cdnProvider,\n customData1: sample?.customData1,\n customData2: sample?.customData2,\n customData3: sample?.customData3,\n customData4: sample?.customData4,\n customData5: sample?.customData5,\n customData6: sample?.customData6,\n customData7: sample?.customData7,\n customData8: sample?.customData8,\n customData9: sample?.customData9,\n customData10: sample?.customData10,\n customData11: sample?.customData11,\n customData12: sample?.customData12,\n customData13: sample?.customData13,\n customData14: sample?.customData14,\n customData15: sample?.customData15,\n customData16: sample?.customData16,\n customData17: sample?.customData17,\n customData18: sample?.customData18,\n customData19: sample?.customData19,\n customData20: sample?.customData20,\n customData21: sample?.customData21,\n customData22: sample?.customData22,\n customData23: sample?.customData23,\n customData24: sample?.customData24,\n customData25: sample?.customData25,\n customData26: sample?.customData26,\n customData27: sample?.customData27,\n customData28: sample?.customData28,\n customData29: sample?.customData29,\n customData30: sample?.customData30,\n customData31: sample?.customData31,\n customData32: sample?.customData32,\n customData33: sample?.customData33,\n customData34: sample?.customData34,\n customData35: sample?.customData35,\n customData36: sample?.customData36,\n customData37: sample?.customData37,\n customData38: sample?.customData38,\n customData39: sample?.customData39,\n customData40: sample?.customData40,\n customData41: sample?.customData41,\n customData42: sample?.customData42,\n customData43: sample?.customData43,\n customData44: sample?.customData44,\n customData45: sample?.customData45,\n customData46: sample?.customData46,\n customData47: sample?.customData47,\n customData48: sample?.customData48,\n customData49: sample?.customData49,\n customData50: sample?.customData50,\n customData51: sample?.customData51,\n customData52: sample?.customData52,\n customData53: sample?.customData53,\n customData54: sample?.customData54,\n customData55: sample?.customData55,\n customData56: sample?.customData56,\n customData57: sample?.customData57,\n customData58: sample?.customData58,\n customData59: sample?.customData59,\n customData60: sample?.customData60,\n customData61: sample?.customData61,\n customData62: sample?.customData62,\n customData63: sample?.customData63,\n customData64: sample?.customData64,\n customData65: sample?.customData65,\n customData66: sample?.customData66,\n customData67: sample?.customData67,\n customData68: sample?.customData68,\n customData69: sample?.customData69,\n customData70: sample?.customData70,\n customData71: sample?.customData71,\n customData72: sample?.customData72,\n customData73: sample?.customData73,\n customData74: sample?.customData74,\n customData75: sample?.customData75,\n customData76: sample?.customData76,\n customData77: sample?.customData77,\n customData78: sample?.customData78,\n customData79: sample?.customData79,\n customData80: sample?.customData80,\n customData81: sample?.customData81,\n customData82: sample?.customData82,\n customData83: sample?.customData83,\n customData84: sample?.customData84,\n customData85: sample?.customData85,\n customData86: sample?.customData86,\n customData87: sample?.customData87,\n customData88: sample?.customData88,\n customData89: sample?.customData89,\n customData90: sample?.customData90,\n customData91: sample?.customData91,\n customData92: sample?.customData92,\n customData93: sample?.customData93,\n customData94: sample?.customData94,\n customData95: sample?.customData95,\n customData96: sample?.customData96,\n customData97: sample?.customData97,\n customData98: sample?.customData98,\n customData99: sample?.customData99,\n customData100: sample?.customData100,\n customUserId: sample?.customUserId,\n domain: sample?.domain,\n experimentName: sample?.experimentName,\n key: sample?.key,\n language: sample?.language,\n path: sample?.path,\n platform: sample?.platform,\n player: sample?.player,\n playerKey: sample?.playerKey,\n playerTech: sample?.playerTech,\n size: sample?.size,\n screenHeight: sample?.screenHeight,\n screenWidth: sample?.screenWidth,\n streamFormat: sample?.streamFormat,\n userAgent: sample?.userAgent,\n userId: sample?.userId,\n version: sample?.version,\n videoBitrate: sample?.videoBitrate,\n videoId: sample?.videoId,\n videoImpressionId: sample?.impressionId,\n videoTitle: sample?.videoTitle,\n videoWindowHeight: sample?.videoWindowHeight,\n videoWindowWidth: sample?.videoWindowWidth,\n };\n}\n\nexport function createErrorAdSample(\n playbackSample: Sample,\n ssaiEngagementErrorData: SsaiEngagementErrorData,\n): AdSample {\n return buildAdSample({\n playbackSample,\n currentAdImpressionId: ssaiEngagementErrorData.currentAdImpressionId,\n adIndex: ssaiEngagementErrorData.adIndex,\n currentAdMetadata: ssaiEngagementErrorData.currentAdMetadata,\n quartile: undefined,\n quartileMetadata: undefined,\n errorCode: ssaiEngagementErrorData.analyticsError.code,\n errorMessage: ssaiEngagementErrorData.analyticsError.message,\n errorSeverity: ssaiEngagementErrorData.analyticsError.severity,\n timeSinceAdStartedInMs: ssaiEngagementErrorData.timeSinceAdStartedInMs,\n });\n}\n\nexport function createStartedAdSample(\n playbackSample: Sample,\n ssaiEngagementStartedData: SsaiEngagementStartedData,\n): AdSample {\n return buildAdSample({\n playbackSample,\n currentAdImpressionId: ssaiEngagementStartedData.currentAdImpressionId,\n adIndex: ssaiEngagementStartedData.adIndex,\n currentAdMetadata: ssaiEngagementStartedData.currentAdMetadata,\n quartile: 'started',\n quartileMetadata: undefined,\n errorCode: undefined,\n errorMessage: undefined,\n errorSeverity: undefined,\n timeSinceAdStartedInMs: undefined,\n });\n}\n\nexport function createQuartileAdSample(\n playbackSample: Sample,\n ssaiEngagementQuartileData: SsaiEngagementQuartileData,\n): AdSample {\n return buildAdSample({\n playbackSample,\n currentAdImpressionId: ssaiEngagementQuartileData.currentAdImpressionId,\n adIndex: ssaiEngagementQuartileData.adIndex,\n currentAdMetadata: ssaiEngagementQuartileData.currentAdMetadata,\n quartile: ssaiEngagementQuartileData.quartile,\n quartileMetadata: ssaiEngagementQuartileData.quartileMetadata,\n timeSinceAdStartedInMs: ssaiEngagementQuartileData.timeSinceAdStartedInMs,\n errorCode: undefined,\n errorMessage: undefined,\n errorSeverity: undefined,\n });\n}\n\nfunction buildAdSample({\n playbackSample,\n currentAdImpressionId,\n adIndex,\n currentAdMetadata,\n quartile,\n quartileMetadata,\n errorCode,\n errorMessage,\n errorSeverity,\n timeSinceAdStartedInMs,\n}: {\n adIndex: number;\n currentAdImpressionId: string;\n currentAdMetadata: InternalSsaiMetadata;\n errorCode: number | undefined;\n errorMessage: string | undefined;\n errorSeverity: ErrorSeverity | undefined;\n playbackSample: Sample;\n quartile: 'started' | SsaiAdQuartile | undefined;\n quartileMetadata: SsaiAdQuartileMetadata | undefined;\n timeSinceAdStartedInMs: number | undefined;\n}): AdSample {\n const adEngagementSample: AdSample = {\n ...createAdSampleFromSample(playbackSample),\n adId: currentAdMetadata?.adId,\n adImpressionId: currentAdImpressionId,\n adIndex: adIndex,\n adPosition: currentAdMetadata?.adPosition,\n adSystem: currentAdMetadata?.adSystem,\n adType: 2,\n errorCode: errorCode,\n errorMessage: errorMessage,\n errorSeverity: errorSeverity,\n time: Date.now(),\n timeSinceAdStartedInMs: timeSinceAdStartedInMs,\n };\n\n // set quartile data\n switch (quartile) {\n case 'started':\n adEngagementSample.started = 1;\n break;\n case 'first':\n adEngagementSample.quartile1 = 1;\n adEngagementSample.quartile1FailedBeaconUrl = quartileMetadata?.failedBeaconUrl;\n break;\n case 'midpoint':\n adEngagementSample.midpoint = 1;\n adEngagementSample.midpointFailedBeaconUrl = quartileMetadata?.failedBeaconUrl;\n break;\n case 'third':\n adEngagementSample.quartile3 = 1;\n adEngagementSample.quartile3FailedBeaconUrl = quartileMetadata?.failedBeaconUrl;\n break;\n case 'completed':\n adEngagementSample.completed = 1;\n adEngagementSample.completedFailedBeaconUrl = quartileMetadata?.failedBeaconUrl;\n break;\n }\n\n // set ssai customData\n const customData = currentAdMetadata?.customData;\n if (isNotNullish(customData)) {\n customDataValuesKeys.forEach((key) => {\n if (customData[key]) {\n adEngagementSample[key] = customData[key];\n }\n });\n }\n\n return adEngagementSample;\n}\n\n/**\n * Returns the current timestamp in milliseconds using the `performance.now()` method if available\n * to ensure monotonic timestamps; otherwise, it falls back to using `Date.now()`.\n *\n * Date.now() is dependent on the system clock and not monotonic, it may have been impacted by system\n * and user clock adjustments. The performance.now() method is relative to the timeOrigin property\n * which is a monotonic clock: its current time never decreases and isn't subject to adjustments.\n */\nexport function getCurrentMonotonicTimestampInMs(): number {\n const performanceNow = getGlobalPerformanceNow();\n if (isNullish(performanceNow)) {\n return Date.now();\n }\n\n // floor to return integer value (not double as performance.now() returns)\n return Math.floor(performanceNow);\n}\n\nexport function getMonotonicTimestampInMsSince(timestampInMs: number | undefined): number | undefined {\n if (isNullish(timestampInMs)) {\n return undefined;\n }\n\n return getCurrentMonotonicTimestampInMs() - timestampInMs;\n}\n","export enum AD_TYPE {\n NO_AD = 0,\n CSAI = 1,\n SSAI = 2,\n}\n","export enum CdnProvider {\n AKAMAI = 'akamai',\n BITGRAVITY = 'bitgravity',\n CHINACACHE = 'chinacache',\n CLOUDFLARE = 'cloudflare',\n CLOUDFRONT = 'cloudfront',\n FASTLY = 'fastly',\n MAXCDN = 'maxcdn',\n}\n","import {ErrorSeverity} from '../types/AnalyticsConfig';\n\nexport class ErrorCode {\n static BITMOVIN_PLAYER_LICENSING_ERROR = new ErrorCode(1103, '');\n static SETUP_MISSING_LICENSE_WHITELIST = new ErrorCode(1105, '');\n static QUALITY_CHANGE_THRESHOLD_EXCEEDED = new ErrorCode(\n 10000,\n 'ANALYTICS_QUALITY_CHANGE_THRESHOLD_EXCEEDED',\n 'INFO',\n );\n static BUFFERING_TIMEOUT_REACHED = new ErrorCode(10001, 'ANALYTICS_BUFFERING_TIMEOUT_REACHED');\n static VIDEO_STARTUP_TIMEOUT_REACHED = new ErrorCode(10002, 'ANALYTICS_VIDEOSTART_TIMEOUT_REACHED');\n\n private constructor(\n readonly code: number,\n readonly message: string,\n readonly errorSeverity: ErrorSeverity = 'CRITICAL',\n ) {}\n}\n","import type {\n AnalyticsEventBase,\n CustomDataValuesEvent,\n ErrorEvent,\n QualityChangeEvent,\n SourceChangeEvent,\n} from '../types/EventData';\n\n/**\n * If we specify the name of our initial state, then an implicit 'startup' initial event will be created by JSM\n * and fired when the state machine is constructed.\n *\n * Because that implicit JSM initial event is called 'startup', it could cause confusion with our \"STARTUP state\", so for\n * that reason we will use custom JSM initial event name, to be able to distinguish it from our other {@link Event}s.\n *\n * This event should not be used in the application code, it is only used by the JSM library!\n *\n * @see https://github.com/jakesgordon/javascript-state-machine/blob/2.4.0/README.md#initialization-options\n */\nexport const JSM_INITIAL_EVENT = 'jsm-initial';\n\nexport enum Event {\n AUDIO_CHANGE = 'audioChange',\n AUDIOTRACK_CHANGED = 'audioTrackChanged',\n CUSTOM_DATA_CHANGE = 'customDataChange',\n /**\n * Fired when the player has finished playback.\n */\n END = 'end',\n END_AD = 'adEnd',\n END_BUFFERING = 'endBuffering',\n END_CAST = 'endCasting',\n END_FULLSCREEN = 'endFullscreen',\n ERROR = 'playerError',\n /**\n * Custom Event fired by Analytics State Machine. Used to immediately transition out of the QUALITY_CHANGE State\n * back to PLAYING State where the quality change was tracked.\n */\n FINISH_QUALITY_CHANGE = 'finishQualityChange',\n /**\n * Manually fired when a source load with autoplay is detected.\n * Required for accurate VST (video startup time) measurement: Some players delay sending PLAY events until\n * manifest/content is loaded, making VST unreliable if calculated from player events alone.\n * For autoplay scenarios, VST is measured as the time from source load to the first\n * PLAYING or TIMEUPDATE event from the player.\n */\n LOADSTART_AUTOPLAY = 'loadstartAutoplay',\n MANUAL_SOURCE_CHANGE = 'manualSourceChangeInitiated',\n MUTE = 'mute',\n PAUSE = 'pause',\n PLAY = 'play',\n PLAYING = 'playing',\n /**\n * Fired when the player is ready to play.\n */\n READY = 'ready',\n SCREEN_RESIZE = 'resize',\n SEEK = 'seek',\n SEEKED = 'seeked',\n SOURCE_LOADED = 'sourceLoaded',\n SOURCE_UNLOADED = 'sourceUnloaded',\n START_AD = 'adStart',\n START_BUFFERING = 'startBuffering',\n START_CAST = 'startCasting',\n START_FULLSCREEN = 'startFullscreen',\n SUBTITLE_CHANGE = 'subtitleChange',\n TIMECHANGED = 'timechanged',\n UN_MUTE = 'unMute',\n /**\n * Fired when page with player is closed or when the player is unloaded/destroyed.\n */\n UNLOAD = 'unload',\n VIDEO_CHANGE = 'videoChange',\n VIDEOSTART_TIMEOUT = 'VIDEOSTART_TIMEOUT',\n}\n\nexport interface EventMap {\n [Event.READY]: AnalyticsEventBase;\n [Event.SOURCE_LOADED]: AnalyticsEventBase;\n [Event.PLAY]: AnalyticsEventBase;\n [Event.PLAYING]: AnalyticsEventBase | CustomDataValuesEvent;\n [Event.PAUSE]: AnalyticsEventBase | CustomDataValuesEvent;\n [Event.TIMECHANGED]: AnalyticsEventBase;\n [Event.SEEK]: AnalyticsEventBase;\n [Event.SEEKED]: AnalyticsEventBase;\n [Event.START_CAST]: AnalyticsEventBase;\n [Event.END_CAST]: AnalyticsEventBase;\n [Event.START_BUFFERING]: AnalyticsEventBase;\n [Event.END_BUFFERING]: AnalyticsEventBase;\n [Event.AUDIOTRACK_CHANGED]: AnalyticsEventBase;\n [Event.AUDIO_CHANGE]: QualityChangeEvent;\n [Event.VIDEO_CHANGE]: QualityChangeEvent;\n [Event.FINISH_QUALITY_CHANGE]: AnalyticsEventBase;\n [Event.START_FULLSCREEN]: AnalyticsEventBase;\n [Event.END_FULLSCREEN]: AnalyticsEventBase;\n [Event.START_AD]: AnalyticsEventBase;\n [Event.SUBTITLE_CHANGE]: AnalyticsEventBase;\n [Event.END_AD]: AnalyticsEventBase;\n [Event.MUTE]: AnalyticsEventBase;\n [Event.UN_MUTE]: AnalyticsEventBase;\n [Event.ERROR]: ErrorEvent;\n [Event.SCREEN_RESIZE]: AnalyticsEventBase;\n [Event.UNLOAD]: AnalyticsEventBase;\n [Event.END]: AnalyticsEventBase;\n [Event.SOURCE_UNLOADED]: AnalyticsEventBase;\n [Event.MANUAL_SOURCE_CHANGE]: SourceChangeEvent;\n [Event.VIDEOSTART_TIMEOUT]: AnalyticsEventBase;\n [Event.CUSTOM_DATA_CHANGE]: AnalyticsEventBase;\n [Event.LOADSTART_AUTOPLAY]: AnalyticsEventBase;\n}\n","import {endsWith} from '../utils/stringUtils';\n\nexport const MIMETypes = {\n MP4: 'video/mp4',\n WEBM: 'video/webm',\n HLS: 'application/x-mpegURL',\n DASH: 'application/dash+xml',\n} as const;\n\n/**\n * @deprecated use {@link getStreamTypesFromURL} directly, when we want to detect {@link StreamTypes} from URL\n *\n * @remarks\n *\n * In our current code, it is visible that detection of MIME Type is only used as \"an additional step\" between\n * stream URL and stream type:\n * - we parse stream URL to detect MIME type\n * - we parse the detected MIME type to get a stream type\n *\n * Because we are not sending the detected MIME type in sample and because we can get {@link StreamTypes} directly from\n * stream URL, we should stop using this MIME type detection code.\n */\nexport function getMIMETypeFromFileExtension(url: string): string | undefined {\n const urlPath = url.split(/[?#]/)[0].toLowerCase();\n\n if (endsWith(urlPath, '.m3u8')) {\n return MIMETypes.HLS;\n }\n if (endsWith(urlPath, '.mp4') || endsWith(urlPath, '.m4v') || endsWith(urlPath, '.m4a')) {\n return MIMETypes.MP4;\n }\n if (endsWith(urlPath, '.webm')) {\n return MIMETypes.WEBM;\n }\n if (endsWith(urlPath, '.mpd')) {\n return MIMETypes.DASH;\n }\n\n return undefined;\n}\n","export enum PAGE_LOAD_TYPE {\n FOREGROUND = 1,\n BACKGROUND = 2,\n}\n","export enum Player {\n BITMOVIN = 'bitmovin',\n BITMOVIN_PWX = 'bitmovin-pwx',\n CHROMECAST_SHAKA = 'chromecast-shaka',\n HLSJS = 'hlsjs',\n HTML5 = 'html5',\n JW = 'jw',\n RADIANT = 'radiant',\n SHAKA = 'shaka',\n THEOPLAYER = 'theoplayer',\n VIDEOJS = 'videojs',\n}\n","export enum PlayerSize {\n Fullscreen = 'FULLSCREEN',\n Window = 'WINDOW',\n}\n","import {endsWith, isBlank} from '../utils/stringUtils';\nimport {isNullish} from '../utils/Utils';\n\nimport {MIMETypes} from './MIMETypes';\n\nexport enum StreamTypes {\n dash = 'dash',\n hls = 'hls',\n prog = 'progressive',\n}\n\nexport function getStreamTypesFromURL(url: string | undefined): StreamTypes | undefined {\n if (isNullish(url) || isBlank(url)) {\n return undefined;\n }\n\n const urlPath = url.split(/[?#]/)[0].toLowerCase();\n\n if (endsWith(urlPath, '.m3u8')) {\n return StreamTypes.hls;\n }\n if (endsWith(urlPath, '.mp4') || endsWith(urlPath, '.m4v') || endsWith(urlPath, '.m4a')) {\n return StreamTypes.prog;\n }\n if (endsWith(urlPath, '.webm')) {\n return StreamTypes.prog;\n }\n if (endsWith(urlPath, '.mpd')) {\n return StreamTypes.dash;\n }\n\n return undefined;\n}\n\nexport function getStreamTypeFromMIMEType(mimeType: string): StreamTypes | undefined {\n const MIME_TYPE_TO_STREAM_TYPE_MAP = {\n [MIMETypes.MP4]: StreamTypes.prog,\n [MIMETypes.WEBM]: StreamTypes.prog,\n [MIMETypes.HLS]: StreamTypes.hls,\n [MIMETypes.DASH]: StreamTypes.dash,\n };\n\n return MIME_TYPE_TO_STREAM_TYPE_MAP[mimeType];\n}\n","import {Event} from './Event';\n\nexport enum VideoStartFailedReason {\n PAGE_CLOSED = 'PAGE_CLOSED',\n PLAYER_ERROR = 'PLAYER_ERROR',\n TIMEOUT = 'TIMEOUT',\n UNKNOWN = 'UNKNOWN',\n}\n\nexport function createVideoStartFailedReason(stateMachineEvent: string | undefined): VideoStartFailedReason {\n switch (stateMachineEvent) {\n case Event.ERROR:\n return VideoStartFailedReason.PLAYER_ERROR;\n case Event.UNLOAD:\n return VideoStartFailedReason.PAGE_CLOSED;\n case Event.MANUAL_SOURCE_CHANGE:\n return VideoStartFailedReason.PAGE_CLOSED;\n case Event.SOURCE_UNLOADED:\n return VideoStartFailedReason.PAGE_CLOSED;\n case Event.VIDEOSTART_TIMEOUT:\n return VideoStartFailedReason.TIMEOUT;\n\n default:\n return VideoStartFailedReason.UNKNOWN;\n }\n}\n","import {isNotNullish} from '../utils/Utils';\n\nimport {FeatureConfig} from './FeatureConfig';\n\nexport abstract class Feature<TConfigContainer, TConfig extends FeatureConfig> {\n private _config?: TConfig = undefined;\n private _isEnabled = true;\n\n get config(): TConfig | undefined {\n return this._config;\n }\n\n get isEnabled(): boolean {\n return this._isEnabled;\n }\n\n abstract reset(): void;\n abstract enabled(): void;\n abstract disabled(): void;\n abstract configured(authenticated: boolean, config?: TConfig): void;\n\n disable() {\n this._isEnabled = false;\n this.disabled();\n }\n\n configure(authenticated: boolean, configContainer?: TConfigContainer): TConfig | undefined {\n if (isNotNullish(configContainer)) {\n this._config = this.extractConfig(configContainer);\n }\n this.configured(authenticated, this._config);\n return this._config;\n }\n\n abstract extractConfig(configContainer: TConfigContainer): TConfig | undefined;\n}\n","import {logger} from '../utils/Logger';\n\nimport {Feature} from './Feature';\nimport {FeatureConfig} from './FeatureConfig';\n\nexport class FeatureManager<TConfigContainer> {\n private features: Array<Feature<TConfigContainer, FeatureConfig>> = [];\n\n registerFeatures(features: Array<Feature<TConfigContainer, FeatureConfig>>) {\n this.features = features;\n }\n\n unregisterFeatures() {\n this.features.forEach((feature) => feature.disable());\n this.features = [];\n }\n\n resetFeatures() {\n this.features.forEach((feature) => feature.reset());\n }\n\n configureFeatures(authenticated: boolean, featureConfigs?: TConfigContainer) {\n this.features = this.features.filter((feature) => {\n const config = feature.configure(authenticated, featureConfigs);\n if (!authenticated || config?.enabled !== true) {\n logger.log(`Disabling feature ${feature.constructor.name} as it isn't enabled according to license callback.`);\n feature.disable();\n return false;\n }\n return true;\n });\n this.features.forEach((feature) => feature.enabled());\n }\n}\n","import {CollectorConfig} from '../../types/AnalyticsConfig';\nimport {post} from '../../utils/Http';\nimport {ANALYTICS_BACKEND_BASE_URL} from '../../utils/Settings';\nimport {isNotNullish, joinUrls} from '../../utils/Utils';\nimport {HttpRequest} from '../httprequesttracking/HttpRequest';\n\nimport {ErrorData} from './ErrorData';\nimport {ErrorDetail} from './ErrorDetail';\n\nexport class ErrorDetailBackend {\n get queue(): ReadonlyArray<ErrorDetail> {\n return this._queue;\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(value: boolean) {\n this._enabled = value;\n }\n\n static copyErrorDetailTruncateStringsAndUrls(\n errorDetail: ErrorDetail,\n maxStringLength: number,\n maxUrlLength: number,\n ): ErrorDetail {\n return {\n ...errorDetail,\n message: errorDetail.message?.substr(0, maxStringLength),\n data: this.copyErrorDataTruncateStrings(errorDetail.data, maxStringLength),\n httpRequests: errorDetail.httpRequests?.map((request) => this.copyHttpRequestTruncateUrls(request, maxUrlLength)),\n };\n }\n\n static copyHttpRequestTruncateUrls(httpRequest: HttpRequest, maxLength: number): HttpRequest {\n return {\n ...httpRequest,\n url: httpRequest.url?.substr(0, maxLength),\n lastRedirectLocation: httpRequest.lastRedirectLocation?.substr(0, maxLength),\n };\n }\n\n static copyErrorDataTruncateStrings(errorData: ErrorData, maxStringLength: number): ErrorData {\n return {\n ...errorData,\n exceptionMessage: errorData.exceptionMessage?.substr(0, maxStringLength),\n additionalData: errorData.additionalData?.substr(0, maxStringLength),\n };\n }\n\n static copyErrorDetailTruncateHttpRequests(errorDetail: ErrorDetail, maxRequests: number): ErrorDetail {\n return {\n ...errorDetail,\n httpRequests: errorDetail.httpRequests?.slice(-maxRequests),\n };\n }\n\n // We use these as upper limits to avoid clients bombing us with data, actual truncation to documented limits is\n // happening in ingress\n private static MAX_URL_LENGTH = 450;\n private static MAX_STRING_LENGTH = 2000;\n\n private readonly backendUrl: string;\n private readonly _queue: ErrorDetail[] = [];\n private _enabled = false;\n\n constructor(collectorConfig: CollectorConfig | undefined) {\n this.backendUrl = joinUrls(collectorConfig?.backendUrl ?? ANALYTICS_BACKEND_BASE_URL, '/analytics/error');\n }\n\n limitHttpRequestsOfQueuedErrorDetails(max: number) {\n this._queue.forEach((value, index) => {\n this._queue[index] = ErrorDetailBackend.copyErrorDetailTruncateHttpRequests(value, max);\n });\n }\n\n send(errorDetail: ErrorDetail) {\n const errorDetailCopy = ErrorDetailBackend.copyErrorDetailTruncateStringsAndUrls(\n errorDetail,\n ErrorDetailBackend.MAX_STRING_LENGTH,\n ErrorDetailBackend.MAX_URL_LENGTH,\n );\n if (this.enabled) {\n post(this.backendUrl, errorDetailCopy);\n } else {\n this._queue.push(errorDetailCopy);\n }\n }\n\n flush() {\n const copy = [...this._queue];\n let element = copy.shift();\n while (isNotNullish(element)) {\n this.removeFromQueue(element);\n this.send(element);\n element = copy.shift();\n }\n }\n\n clear() {\n this._queue.splice(0, this._queue.length);\n }\n\n private removeFromQueue(element: ErrorDetail) {\n const index = this._queue.findIndex((value) => value === element);\n if (index >= 0) {\n this._queue.splice(index, 1);\n }\n }\n}\n","import {Subscribable} from '../../core/EventDispatcher';\nimport {CollectorConfig} from '../../types/AnalyticsConfig';\nimport {FeatureConfigContainer} from '../../types/FeatureConfigContainer';\nimport {logger} from '../../utils/Logger';\nimport {getCurrentTimestamp, isNullish, tryJSONStringify} from '../../utils/Utils';\nimport {VERSION} from '../../utils/Version';\nimport {Feature} from '../Feature';\nimport {HttpRequestTracking} from '../httprequesttracking/HttpRequestTracking';\n\nimport {ErrorDetail} from './ErrorDetail';\nimport {ErrorDetailBackend} from './ErrorDetailBackend';\nimport {ErrorDetailTrackingConfig} from './ErrorDetailTrackingConfig';\nimport {OnErrorDetailEventObject} from './OnErrorDetailEventObject';\n\nexport interface ErrorDetailTrackingSettingsProvider {\n readonly licenseKey: string;\n readonly domain: string;\n readonly impressionId: string;\n readonly collectorConfig?: CollectorConfig;\n}\n\nexport class ErrorDetailTracking extends Feature<FeatureConfigContainer, ErrorDetailTrackingConfig> {\n private errorIndex = 0;\n\n constructor(\n private settingsProvider: ErrorDetailTrackingSettingsProvider,\n private backend: ErrorDetailBackend,\n private subscribables: Array<Subscribable<OnErrorDetailEventObject>>,\n private httpRequestTracking: HttpRequestTracking | undefined,\n ) {\n super();\n subscribables.forEach((subscribable) => subscribable.subscribe(this.onErrorHandler));\n }\n\n reset(): void {\n this.httpRequestTracking?.reset();\n this.errorIndex = 0;\n }\n\n enabled(): void {\n this.backend.enabled = true;\n this.backend.flush();\n }\n\n disabled(): void {\n this.errorIndex = 0;\n this.httpRequestTracking?.disable();\n this.backend.clear();\n this.subscribables.forEach((subscribable) => subscribable.unsubscribe(this.onErrorHandler));\n }\n\n configured(_authenticated: boolean, config?: ErrorDetailTrackingConfig): void {\n const maxRequests = Math.max(config?.numberOfHttpRequests ?? 0, 0);\n this.httpRequestTracking?.configure(maxRequests);\n this.backend.limitHttpRequestsOfQueuedErrorDetails(maxRequests);\n }\n\n extractConfig(configContainer: FeatureConfigContainer): ErrorDetailTrackingConfig | undefined {\n return configContainer.errorDetails;\n }\n\n private onErrorHandler = (event: OnErrorDetailEventObject) => {\n try {\n if (!this.isEnabled) {\n return;\n }\n\n const httpRequests = this.httpRequestTracking?.httpRequests;\n const httpRequestsCopy = isNullish(httpRequests) ? undefined : [...httpRequests];\n const errorIndex = this.errorIndex;\n this.errorIndex++;\n\n const errorDetail: ErrorDetail = {\n platform: 'web',\n licenseKey: this.settingsProvider.licenseKey,\n domain: this.settingsProvider.domain,\n impressionId: this.settingsProvider.impressionId,\n analyticsVersion: VERSION,\n errorId: errorIndex,\n timestamp: getCurrentTimestamp(),\n code: event.code,\n message: event.message,\n data: event.errorData ?? {\n additionalData: undefined,\n exceptionMessage: undefined,\n exceptionStacktrace: undefined,\n },\n httpRequests: httpRequestsCopy,\n severity: event.severity,\n };\n\n logger.log(`ErrorDetailTracking.onError: ${tryJSONStringify(errorDetail)}`);\n this.backend.send(errorDetail);\n } catch (error) {\n logger.error(`ErrorDetailTracking.onError: Error in handler`, error);\n }\n };\n}\n","import {getCustomDataString, transferCustomDataFields} from '../utils/Utils';\n\nexport interface CustomDataValues {\n customData1?: string;\n customData2?: string;\n customData3?: string;\n customData4?: string;\n customData5?: string;\n customData6?: string;\n customData7?: string;\n customData8?: string;\n customData9?: string;\n customData10?: string;\n customData11?: string;\n customData12?: string;\n customData13?: string;\n customData14?: string;\n customData15?: string;\n customData16?: string;\n customData17?: string;\n customData18?: string;\n customData19?: string;\n customData20?: string;\n customData21?: string;\n customData22?: string;\n customData23?: string;\n customData24?: string;\n customData25?: string;\n customData26?: string;\n customData27?: string;\n customData28?: string;\n customData29?: string;\n customData30?: string;\n customData31?: string;\n customData32?: string;\n customData33?: string;\n customData34?: string;\n customData35?: string;\n customData36?: string;\n customData37?: string;\n customData38?: string;\n customData39?: string;\n customData40?: string;\n customData41?: string;\n customData42?: string;\n customData43?: string;\n customData44?: string;\n customData45?: string;\n customData46?: string;\n customData47?: string;\n customData48?: string;\n customData49?: string;\n customData50?: string;\n customData51?: string;\n customData52?: string;\n customData53?: string;\n customData54?: string;\n customData55?: string;\n customData56?: string;\n customData57?: string;\n customData58?: string;\n customData59?: string;\n customData60?: string;\n customData61?: string;\n customData62?: string;\n customData63?: string;\n customData64?: string;\n customData65?: string;\n customData66?: string;\n customData67?: string;\n customData68?: string;\n customData69?: string;\n customData70?: string;\n customData71?: string;\n customData72?: string;\n customData73?: string;\n customData74?: string;\n customData75?: string;\n customData76?: string;\n customData77?: string;\n customData78?: string;\n customData79?: string;\n customData80?: string;\n customData81?: string;\n customData82?: string;\n customData83?: string;\n customData84?: string;\n customData85?: string;\n customData86?: string;\n customData87?: string;\n customData88?: string;\n customData89?: string;\n customData90?: string;\n customData91?: string;\n customData92?: string;\n customData93?: string;\n customData94?: string;\n customData95?: string;\n customData96?: string;\n customData97?: string;\n customData98?: string;\n customData99?: string;\n customData100?: string;\n experimentName?: string;\n}\n\n/**\n * Lists all keys of the {@see CustomDataValues} interface.\n */\nexport const customDataValuesKeys: Array<keyof CustomDataValues> = [\n 'customData1',\n 'customData2',\n 'customData3',\n 'customData4',\n 'customData5',\n 'customData6',\n 'customData7',\n 'customData8',\n 'customData9',\n 'customData10',\n 'customData11',\n 'customData12',\n 'customData13',\n 'customData14',\n 'customData15',\n 'customData16',\n 'customData17',\n 'customData18',\n 'customData19',\n 'customData20',\n 'customData21',\n 'customData22',\n 'customData23',\n 'customData24',\n 'customData25',\n 'customData26',\n 'customData27',\n 'customData28',\n 'customData29',\n 'customData30',\n 'customData31',\n 'customData32',\n 'customData33',\n 'customData34',\n 'customData35',\n 'customData36',\n 'customData37',\n 'customData38',\n 'customData39',\n 'customData40',\n 'customData41',\n 'customData42',\n 'customData43',\n 'customData44',\n 'customData45',\n 'customData46',\n 'customData47',\n 'customData48',\n 'customData49',\n 'customData50',\n 'customData51',\n 'customData52',\n 'customData53',\n 'customData54',\n 'customData55',\n 'customData56',\n 'customData57',\n 'customData58',\n 'customData59',\n 'customData60',\n 'customData61',\n 'customData62',\n 'customData63',\n 'customData64',\n 'customData65',\n 'customData66',\n 'customData67',\n 'customData68',\n 'customData69',\n 'customData70',\n 'customData71',\n 'customData72',\n 'customData73',\n 'customData74',\n 'customData75',\n 'customData76',\n 'customData77',\n 'customData78',\n 'customData79',\n 'customData80',\n 'customData81',\n 'customData82',\n 'customData83',\n 'customData84',\n 'customData85',\n 'customData86',\n 'customData87',\n 'customData88',\n 'customData89',\n 'customData90',\n 'customData91',\n 'customData92',\n 'customData93',\n 'customData94',\n 'customData95',\n 'customData96',\n 'customData97',\n 'customData98',\n 'customData99',\n 'customData100',\n\n 'experimentName',\n];\n\n/**\n * The number of CustomDataXX fields in {@see CustomDataValues}.\n */\nexport const customDataFieldCount = customDataValuesKeys.filter((i) => i.match('customData\\\\d+')).length;\n\n/**\n * We are extracting the customData fields explicitly to make sure that there is not a different object passed\n */\nexport const extractCustomDataFieldsOnly = (input: CustomDataValues): CustomDataValues => {\n const retVal: CustomDataValues = {};\n customDataValuesKeys.forEach((key) => {\n if (input[key]) {\n retVal[key] = input[key];\n }\n });\n return retVal;\n};\n\nexport const sanitizeCustomDataValues = (customDataValues: CustomDataValues): CustomDataValues => {\n const extracted = extractCustomDataFieldsOnly(customDataValues);\n\n const sanitizedCustomDataValues: CustomDataValues = {};\n transferCustomDataFields(extracted, sanitizedCustomDataValues);\n // fix a bug of transferCustomDataFields that does not transfer 'experimentName' field, because it is not named 'customDataXX'\n // should be fixed with https://bitmovin.atlassian.net/browse/AN-5182\n sanitizedCustomDataValues.experimentName = getCustomDataString(extracted.experimentName);\n\n return sanitizedCustomDataValues;\n};\n","import {FeatureConfigContainer} from './FeatureConfigContainer';\n\nexport interface LicensingRequest {\n key?: string;\n domain: string;\n version: string;\n}\n\nexport enum LicensingResult {\n Denied = 'denied',\n Granted = 'granted',\n Skip = 'skip',\n}\n\nexport interface LicensingResponse {\n status: LicensingResult;\n message: string;\n features?: FeatureConfigContainer;\n}\n\nexport type LicenseCallFunc = (\n key: string,\n domain: string,\n version: string,\n baseUrl: string,\n) => Promise<LicensingResponse>;\n","import {PlayerSize} from '../enums/PlayerSize';\nimport {StreamTypes} from '../enums/StreamTypes';\nimport {isNullish} from '../utils/Utils';\n\nexport interface PlaybackInfo {\n audioBitrate?: number;\n audioCodec?: string;\n audioLanguage?: string;\n castTech?: string;\n droppedFrames: number;\n isCasting?: boolean;\n isLive?: boolean;\n isMuted?: boolean;\n m3u8Url?: string;\n mpdUrl?: string;\n playerTech?: string;\n progUrl?: string;\n screenHeight?: number;\n screenWidth?: number;\n size?: PlayerSize;\n streamFormat?: string;\n subtitleEnabled?: boolean;\n subtitleLanguage?: string;\n videoBitrate?: number;\n videoCodec?: string;\n videoDuration?: number;\n videoPlaybackHeight?: number;\n videoPlaybackWidth?: number;\n videoTitle?: string;\n videoWindowHeight?: number;\n videoWindowWidth?: number;\n}\n\nexport function normalizeVideoDuration(playerVideoDuration: number | null | undefined): number {\n // This covers Live streams and any case in which the duration is not known\n // which should report 0 as videoDuration\n if (isNullish(playerVideoDuration) || Number.isNaN(playerVideoDuration) || playerVideoDuration === Infinity) {\n return 0;\n }\n return playerVideoDuration;\n}\n\nexport function buildPlaybackInfoStreamTypeFields(\n streamType: StreamTypes | undefined,\n streamUrl: string | undefined,\n): Pick<PlaybackInfo, 'm3u8Url' | 'mpdUrl' | 'progUrl' | 'streamFormat'> {\n const DEFAULT_RESULT = {\n // set the stream type as it is (except null, that should be converted to undefined)\n streamFormat: streamType ?? undefined,\n // If the stream url is there, set it as \"progUrl\", even when the stream type is not recognized (unknown / nullish).\n // Why?\n // There was no clear reason why when this utility fn was created, it was just current written code/behavior\n // of our adapters, and for that reason it was copy&pasted here.\n progUrl: streamUrl,\n };\n\n if (isNullish(streamType)) {\n return DEFAULT_RESULT;\n }\n\n if (streamType === StreamTypes.dash) {\n return {streamFormat: streamType, mpdUrl: streamUrl};\n }\n if (streamType === StreamTypes.hls) {\n return {streamFormat: streamType, m3u8Url: streamUrl};\n }\n if (streamType === StreamTypes.prog) {\n return {streamFormat: streamType, progUrl: streamUrl};\n }\n\n return DEFAULT_RESULT;\n}\n","import type {VideoStartFailedReason} from '../enums/VideoStartFailedReason';\n\nimport type {AnalyticsConfig} from './AnalyticsConfig';\nimport type {AnalyticsEventBase, CustomDataValuesEvent, ErrorEvent, QualityChangeEvent} from './EventData';\nimport type {Sample} from './Sample';\nimport type {SourceMetadata} from './SourceMetadata';\n\nexport type HeartbeatPayload = {\n buffered?: Sample['buffered'];\n /**\n * Flag indicating that the event was triggered by a program change.\n *\n * `true` if the event was triggered by a program change, `undefined` otherwise to not set it as a property in the sample.\n */\n isProgramChange?: true;\n played?: Sample['played'];\n /** Flag indicating that the event was triggered by SSAI */\n triggeredBySsai?: boolean;\n};\n\nexport interface StateMachineCallbacks {\n setup: (duration: number, state: string) => void;\n startup: (duration: number, state: string) => void;\n /** Should reset the analytics, update the source metadata, and send a \"program change startup sample\" */\n programChange: (sourceMetadata: SourceMetadata) => void;\n /** Should only update the source metadata in the analytics module, but without sending any sample. */\n updateSourceMetadata: (sourceMetadata: SourceMetadata) => void;\n playing: (duration: number, state: string) => void;\n heartbeat: (duration: number, state: 'buffering' | 'playing', payload: HeartbeatPayload) => void;\n /**\n * Should send a sample with state \"qualitychange\" and duration 0\n */\n qualitychange: (event: QualityChangeEvent) => void;\n /**\n * Should update the qualityInfo on the current sample but not send any sample, e.g when a qualityChange occurs during\n * pause, seeking or buffering or when the QUALITY_CHANGE_THRESHOLD was hit\n */\n updateSampleQualityInfo: (event: QualityChangeEvent) => void;\n audiotrack_changing: () => void;\n pause: (duration: number, state: string) => void;\n /**\n * Should send a sample with `state: \"seeking\"` and `duration` set to the duration of the seeking.\n */\n seeking: (duration: number) => void;\n buffering: (duration: number, state: string) => void;\n error: (event: Readonly<ErrorEvent>) => void;\n /**\n * @deprecated should not be used at all.\n *\n * Instead, the \"end\" player event should transition state machine to PAUSE state\n *\n * https://bitmovin.atlassian.net/browse/AN-5134\n */\n end: (duration: number, state: string) => void;\n unload: (duration: number, state: string) => void;\n ad: (duration: number, state: string) => void;\n mute: () => void;\n unMute: () => void;\n subtitle_changing: () => void;\n setVideoTimeEndFromEvent: (analyticsEventBase: AnalyticsEventBase) => void;\n setVideoTimeStartFromEvent: (analyticsEventBase: AnalyticsEventBase) => void;\n videoStartFailed: (duration: number, reason: VideoStartFailedReason) => void;\n startCasting: (duration: number, event: any) => void;\n casting: (duration: number, event: any) => void;\n manualSourceChange: (event: {config: AnalyticsConfig}) => void;\n initialSourceChange: (event: {config: AnalyticsConfig}) => void;\n muting_ready: (duration: number, state: string, event: any) => void;\n /**\n * Should change {@link CustomDataValues} of analytics module.\n *\n * @remarks\n *\n * It is called via the default \"onleavestate\" state machine callback, and because of that:\n * - it has to match the state name \"CUSTOMDATACHANGE\"\n * - each parameter has to of `undefined` type (unintentionally, it can be called at any time, from any state)\n */\n customdatachange: (\n duration: number | undefined,\n state: string | undefined,\n eventData: CustomDataValuesEvent | undefined,\n ) => void;\n\n /** shuts down the collection and removes/clears all timeouts, intervals, event listeners */\n release: () => void;\n}\n\n/**\n * {@link StateMachineCallbacks} object with each callback set to be empty function (doing nothing).\n *\n * Why?:\n * We need to set it as default value in {@link InternalAdapter} for use case, when {@link InternalAdapter}\n * is already created and listen to player events, but {@link Analytics} was not instantiated/initialized yet (that\n * should set correct {@link StateMachineCallbacks} implementation)\n */\nexport const defaultStateMachineCallbacks: StateMachineCallbacks = {\n setup: () => {},\n startup: () => {},\n programChange: () => {},\n updateSourceMetadata: () => {},\n playing: () => {},\n heartbeat: () => {},\n qualitychange: () => {},\n updateSampleQualityInfo: () => {},\n audiotrack_changing: () => {},\n pause: () => {},\n seeking: () => {},\n buffering: () => {},\n error: () => {},\n end: () => {},\n unload: () => {},\n ad: () => {},\n mute: () => {},\n unMute: () => {},\n subtitle_changing: () => {},\n setVideoTimeEndFromEvent: () => {},\n setVideoTimeStartFromEvent: () => {},\n videoStartFailed: () => {},\n startCasting: () => {},\n casting: () => {},\n manualSourceChange: () => {},\n initialSourceChange: () => {},\n muting_ready: () => {},\n customdatachange: () => {},\n release: () => {},\n};\n","import {appendSsaiRoutingParam, isSsaiRelatedSample} from '../core/ssai/ssaiUtils';\nimport type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\n\nimport {globalScope} from './globalScope';\nimport {post} from './Http';\nimport {joinUrls} from './Utils';\n\nexport class AnalyticsCall {\n private readonly analyticsServerUrl: string;\n private readonly adAnalyticsServerUrl: string;\n\n constructor(baseUrl: string) {\n this.analyticsServerUrl = joinUrls(baseUrl, 'analytics');\n this.adAnalyticsServerUrl = joinUrls(baseUrl, 'analytics/a');\n }\n\n sendRequest(sample: Sample) {\n let analyticsUrl = this.analyticsServerUrl;\n if (isSsaiRelatedSample(sample)) {\n analyticsUrl = appendSsaiRoutingParam(analyticsUrl);\n }\n\n post(analyticsUrl, sample);\n }\n\n sendUnloadRequest(sample: Sample) {\n const sendBeaconFallback = (data: Sample) => this.sendRequestSynchronous(data);\n\n let analyticsUrl = this.analyticsServerUrl;\n if (isSsaiRelatedSample(sample)) {\n analyticsUrl = appendSsaiRoutingParam(analyticsUrl);\n }\n\n this.trySendBeacon(sendBeaconFallback, analyticsUrl, sample);\n }\n\n private trySendBeacon(\n fallbackFunction: (data: any) => void,\n url: string,\n data: unknown,\n requestHeaders: {[headerName: string]: string} = {},\n ) {\n if (typeof globalScope.navigator?.sendBeacon === 'undefined') {\n fallbackFunction(data);\n } else {\n /**\n * With a Blob we can send payload but also http headers\n * @see https://stackoverflow.com/questions/40523469/navigator-sendbeacon-to-pass-header-information\n */\n const blob = new Blob([JSON.stringify(data)], requestHeaders);\n const success = globalScope.navigator.sendBeacon(url, blob);\n if (!success) {\n fallbackFunction(data);\n }\n }\n }\n\n sendRequestSynchronous(sample: Sample) {\n let analyticsUrl = this.analyticsServerUrl;\n if (isSsaiRelatedSample(sample)) {\n analyticsUrl = appendSsaiRoutingParam(analyticsUrl);\n }\n\n post(analyticsUrl, sample, undefined, false);\n }\n\n sendAdRequest(adSample: AdSample) {\n let adAnalyticsUrl = this.adAnalyticsServerUrl;\n if (isSsaiRelatedSample(adSample)) {\n adAnalyticsUrl = appendSsaiRoutingParam(adAnalyticsUrl);\n }\n\n const sendBeaconFallback = (data: AdSample) => post(adAnalyticsUrl, data);\n this.trySendBeacon(sendBeaconFallback, adAnalyticsUrl, adSample);\n }\n}\n","import {globalScope} from './globalScope';\nimport {isFunction, isNullish} from './Utils';\n\nconst videoFormatCodecMap: {[format: string]: string[]} = {\n avc: ['video/mp4; codecs=\"avc1.42000a\"'],\n vp9: ['video/mp4; codecs=\"vp09.00.50.08\"'],\n av1: ['video/mp4; codecs=\"av01.0.08M.08\"'],\n hevc: ['video/mp4; codecs=\"hev1.1.6.L93.B0\"'],\n};\n\nexport class CodecHelper {\n static get supportedVideoFormats(): string[] | undefined {\n if (isNullish(globalScope.MediaSource?.isTypeSupported) || !isFunction(globalScope.MediaSource.isTypeSupported)) {\n return undefined;\n }\n return Object.getOwnPropertyNames(videoFormatCodecMap).filter((format) =>\n videoFormatCodecMap[format].some((codec) => globalScope.MediaSource.isTypeSupported(codec)),\n );\n }\n}\n","export class EventDebugging {\n event: string | undefined;\n from: string | undefined;\n to: string | undefined;\n timestamp: number;\n eventObject: any;\n\n constructor(\n event: string | undefined,\n from: string | undefined,\n to: string | undefined,\n timestamp: number,\n eventObject: any,\n ) {\n this.event = event;\n this.from = from;\n this.to = to;\n this.timestamp = timestamp;\n this.eventObject = eventObject;\n }\n}\n","import {globalScope} from './globalScope';\nimport {logger} from './Logger';\nimport {isReactNative} from './Utils';\n\n/**\n * Error-first callback for HTTP POST responses.\n *\n * Follows the Node.js error-first convention: the first argument is `null` on success\n * or an `Error` on failure, the second is the parsed JSON response body or `null` on failure.\n *\n * The callback is guaranteed to be called exactly once on every completion path — success,\n * HTTP error, network error, JSON parse failure, or XHR unavailability — so it is safe\n * to wrap in a `Promise` without risk of the Promise never settling.\n *\n * @param error - `null` when the request succeeded, an `Error` describing the failure otherwise.\n * @param response - The parsed JSON response body on success, `null` on failure.\n *\n * @remarks\n * `null` is used instead of `undefined` because `null` signals intentional absence — \"there is\n * no error\" / \"there is no response\" — whereas `undefined` is ambiguous and could mean the value\n * was never set. This matches the Node.js error-first callback convention where `callback(null, data)`\n * is the idiomatic way to indicate success.\n */\ntype PostCallback = (error: Error | null, response: any | null) => void;\n\n/**\n * Sends an HTTP POST request with JSON-serialized body using XMLHttpRequest\n * (or XDomainRequest as a legacy fallback for IE8/IE9).\n *\n * Designed for fire-and-forget analytics calls (no callback) as well as request-response flows\n * like license validation (with callback). When a callback is provided, it is guaranteed to be\n * called exactly once on every completion path.\n *\n * @param url - The endpoint URL to POST to.\n * @param body - The payload to send. Will be serialized via `JSON.stringify`.\n * @param callback - Optional error-first callback invoked when the request completes, see {@link PostCallback}.\n * @param async - Whether to send the request asynchronously. Defaults to `true`.\n * Forced to `true` in React Native (no sync XHR support) and when using legacy XDomainRequest.\n */\nexport function post(url: string, body: any, callback?: PostCallback, async = true): void {\n let xhttp: any;\n let isLegacyXDomainRequestUsed = false;\n\n // Use \"XMLHttpRequest\" by default to make a POST request\n // What about \"fetch\" API?\n // There is no reason to use \"fetch\" API, the only real gains from \"fetch\" are developer experience.\n // The performance difference is negligible in practice. Both ultimately make the same HTTP request\n // over the same network stack. The browser doesn't route fetch faster than XHR.\n if (globalScope.XMLHttpRequest) {\n xhttp = new globalScope.XMLHttpRequest();\n // check for the standard XMLHttpRequest support with CORS (IE10+, all others)\n if (!('withCredentials' in xhttp)) {\n // Context:\n // In IE8/IE9, XMLHttpRequest exists but doesn't support CORS (has no withCredentials).\n // That's exactly why XDomainRequest was invented. Without this check, IE8/IE9 would pick\n // XMLHttpRequest and fail on cross-origin requests.\n xhttp = null;\n }\n }\n\n // Fallback for IE8/IE9 cross-domain AJAX requests, where there is no support for the standard XMLHttpRequest with CORS.\n if (!xhttp && globalScope.XDomainRequest) {\n // XDomainRequest was Internet Explorer's proprietary CORS object (IE8/IE9), Microsoft decided to come up with\n // their own CORS XHR instead of the standard CORS XMLHttpRequest (which is now used in IE10 and later).\n // Since IE10, XDomainRequest has been deprecated and since IE11 removed.\n xhttp = new globalScope.XDomainRequest();\n isLegacyXDomainRequestUsed = true;\n }\n\n // In practice, this should never happen because all modern environments support XMLHttpRequest, and we have a\n // fallback to XDomainRequest for older IE versions. But this is just a safety check to avoid runtime errors in\n // case we're running in some very unusual environment where neither is available.\n if (!xhttp) {\n const message = 'Failed to create POST request, XHR implementation is missing';\n logger.error(message);\n if (callback) {\n callback(new Error(message), null);\n }\n return;\n }\n\n xhttp.onload = () => {\n // ...with XDomainRequest: status is always 0, itself \"onload\" firing is the only indicator of success\n if (isLegacyXDomainRequestUsed) {\n if (callback) {\n try {\n callback(null, JSON.parse(xhttp.responseText));\n } catch (e) {\n const message = 'Failed to parse response';\n logger.error(message, e);\n callback(new Error(message + ': ' + String(e)), null);\n }\n }\n return;\n }\n\n // ...but with XMLHttpRequest we can check the status properly\n if (xhttp.status < 200 || xhttp.status >= 300) {\n const message = 'POST error response:' + xhttp.status + ': ' + xhttp.statusText;\n logger.error(message);\n if (callback) {\n callback(new Error(message), null);\n }\n return;\n }\n\n if (callback) {\n try {\n callback(null, JSON.parse(xhttp.responseText));\n } catch (e) {\n const message = 'Failed to parse response';\n logger.error(message, e);\n callback(new Error(message + ': ' + String(e)), null);\n }\n }\n };\n\n xhttp.onerror = () => {\n const message = 'POST request failed: ' + xhttp.status + ' ' + xhttp.statusText;\n logger.error(message);\n if (callback) {\n callback(new Error(message), null);\n }\n };\n\n try {\n let openAsyncRequest = async;\n\n // React Native doesn't support synchronous XMLHttpRequest\n if (isReactNative() && !openAsyncRequest) {\n openAsyncRequest = true; // Force async mode in React Native environments\n }\n // Legacy XDomainRequest doesn't support synchronous requests\n // Passing false will either be ignored or throw an error depending on the IE version.\n if (isLegacyXDomainRequestUsed) {\n openAsyncRequest = true; // Force async mode when using legacy XDomainRequest\n }\n\n xhttp.open('POST', url, openAsyncRequest);\n\n // Legacy XDomainRequest doesn't support custom headers to be set\n // https://learn.microsoft.com/en-us/archive/blogs/ieinternals/xdomainrequest-restrictions-limitations-and-workarounds\n if (!isLegacyXDomainRequestUsed) {\n // setRequestHeader() must be called AFTER open() and BEFORE send() — calling it before open() will throw an InvalidStateError.\n xhttp.setRequestHeader('Content-Type', 'text/plain');\n }\n\n xhttp.send(JSON.stringify(body));\n } catch (e) {\n const message = 'Failed to send POST request: ' + String(e);\n logger.error(message);\n if (callback) {\n callback(new Error(message), null);\n }\n }\n}\n","import {LicensingResponse} from '../types/LicensingRequest';\n\nimport {post} from './Http';\nimport {logger} from './Logger';\nimport {ANALYTICS_LICENSECALL_TIMEOUT} from './Settings';\nimport {joinUrls} from './Utils';\n\nexport function LicenseCall(key: string, domain: string, version: string, baseUrl: string): Promise<LicensingResponse> {\n const licenseServerUrl = joinUrls(baseUrl, '/licensing');\n const licensingRequest = {\n analyticsVersion: version,\n domain,\n key,\n };\n return new Promise<LicensingResponse>((resolve, reject) => {\n // Safety net: reject the Promise if the callback is never invoked.\n // Http.post guarantees the callback is called on every completion path,\n // but this timeout protects against unforeseen edge cases (e.g., the XHR\n // silently hanging) that would leave the Promise — and with it the entire\n // analytics session — stuck forever.\n const timeout = setTimeout(() => {\n const message = 'License call POST request timed out';\n logger.error(message);\n reject(new Error(message));\n }, ANALYTICS_LICENSECALL_TIMEOUT);\n\n post(licenseServerUrl, licensingRequest, (error, response) => {\n clearTimeout(timeout);\n if (error) {\n reject(error);\n return;\n }\n resolve(response);\n });\n });\n}\n","import {AnalyticsConfig} from '../types/AnalyticsConfig';\n\n/**\n * Uses a Singleton design pattern.\n *\n * We want to ensure that only one object of its kind exists and provides a single point of access to it,\n * to be able to control enabled/disabled `console` logs for customer in whole code base.\n */\nclass Logger {\n private static instance: Logger;\n\n static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n\n return Logger.instance;\n }\n\n private analyticsDebugConfig: Readonly<AnalyticsConfig['debug']>;\n\n private constructor() {}\n\n initialize(analyticsDebugConfig: AnalyticsConfig['debug']) {\n this.analyticsDebugConfig = analyticsDebugConfig;\n }\n\n //#region Console API\n log(message?: unknown, ...optionalParams: unknown[]) {\n if (!this.enabled) {\n return;\n }\n console.log(message, optionalParams); //eslint-disable-line no-console\n }\n\n table(tabularData: unknown, properties?: readonly string[]) {\n if (!this.enabled) {\n return;\n }\n console.table(tabularData, properties); //eslint-disable-line no-console\n }\n\n warn(message?: unknown, ...optionalParams: unknown[]) {\n if (!this.enabled) {\n return;\n }\n console.warn(message, optionalParams); //eslint-disable-line no-console\n }\n\n error(message?: unknown, ...optionalParams: unknown[]) {\n if (!this.enabled) {\n return;\n }\n console.error(message, optionalParams); //eslint-disable-line no-console\n }\n\n /**\n * Outputs an error message to user/customer console.\n *\n * Does not relay on {@link Logger#enabled}! because it should deliver the error information to user/customer.\n */\n errorMessageToUser(message?: unknown, ...optionalParams: unknown[]) {\n console.error(message, ...optionalParams); //eslint-disable-line no-console\n }\n //#endregion\n\n /** `true` if {@link AnalyticsConfig#debug} was set */\n private get enabled() {\n return (this.analyticsDebugConfig as boolean) || false;\n }\n}\n\nexport const padRight = (str: string | undefined, length: number) => {\n const padStr = new Array(length).join(' ');\n return (str + padStr).slice(0, length);\n};\n\nexport const logger = Logger.getInstance();\n","export const MESSAGE_NAMESPACE = 'urn:x-cast:com.bitmovin.analytics.cast';\nexport const ANALYTICS_BACKEND_BASE_URL = 'https://analytics-ingress-global.bitmovin.com';\n\nexport const ANALYTICS_LICENSECALL_TIMEOUT = 1000 * 60;\nexport const ANALYTICS_VIDEOSTART_TIMEOUT = 1000 * 60; // in milliseconds\n\nexport const ANALYTICS_QUALITY_CHANGE_COUNT_THRESHOLD = 50;\nexport const ANALYTICS_QUALITY_CHANGE_COUNT_RESET_INTERVAL = 60 * 60 * 1000;\n\n/**\n * Time (in milliseconds) of consecutive buffering until a BUFFER_TIMEOUT_ERROR is raised.\n */\nexport const ANALYTICS_BUFFER_TIMEOUT = 1000 * 60 * 2;\n\n/**\n * minimal time (in seconds) a seek event should have in order to be recogniced as seek\n */\nexport const ANALYTICS_MIN_SEEK_DIFFERENCE_THRESHOLD = 3;\n\n/**\n * Has to be greater or equal than Ingress side limit (currently 1000).\n */\nexport const SEQUENCE_NUMBER_LIMIT = 1000;\n","import {PAGE_LOAD_TYPE} from '../enums/PageLoadType';\nimport {ErrorSeverity} from '../types/AnalyticsConfig';\nimport type {CustomDataValues} from '../types/CustomDataValues';\nimport * as CustomDataUtils from '../types/CustomDataValues';\n\nimport {isDocumentHidden} from './documentUtils';\nimport {getGlobalNavigatorProduct} from './globalScopeUtils';\nimport {endsWith, startsWith} from './stringUtils';\n\n/**\n * Performs a loose equality check (==), which means it checks for both null and undefined.\n *\n * @returns {value is null | undefined} `true` if the given value is `null` or `undefined`.\n */\nexport const isNullish = (value: unknown): value is null | undefined => value == null;\n\n/**\n *\n * @returns {value is Exclude<unknown, null | undefined>} `true` if the given value is not `null` and is not `undefined`.\n */\nexport const isNotNullish = <T = unknown>(value: T): value is Exclude<T, null | undefined> => !isNullish(value);\n\n/**\n * @returns {value is boolean} `true` if the given value is {@link isNotNullish} and is type of `boolean`.\n */\nexport const isBoolean = (value: unknown): value is boolean => !isNullish(value) && typeof value === 'boolean';\n\nexport const toBoolean = (value: unknown): boolean => Boolean(value).valueOf();\n\n/**\n * Checks if a value is a non-null object.\n *\n * We must exclude `null` explicitly, because `typeof null === \"object\"`\n *\n * @returns {value is Record<string, unknown>} `true` if the value is a non-null object, otherwise `false`.\n */\nexport const isObject = <T extends object>(value: T): value is T => {\n return isNotNullish(value) && typeof value === 'object';\n};\n\n/**\n * Checks if a value is a plain object (not an array, function, or built-in instance).\n *\n * @returns {value is Record<string, unknown>} `true` if the value is a plain object, otherwise `false`.\n */\nexport const isPlainObject = <T extends object>(value: T): value is T => {\n return Object.prototype.toString.call(value) === '[object Object]';\n};\n\n/**\n * Checks if a value is a function.\n *\n * @returns {value is function} `true` if the value is a function, otherwise `false`.\n */\nexport const isFunction = <T extends (...args: unknown[]) => unknown>(value: unknown): value is T =>\n typeof value === 'function';\n\n/**\n * Checks if a value is of type ErrorSeverity.\n *\n * @returns {value is ErrorSeverity} `true` if the value is of type ErrorSeverity, otherwise `false`.\n */\nexport function isErrorSeverity(anything: unknown): anything is ErrorSeverity {\n // invalid, when not defined as one of string values we expect\n return anything === 'CRITICAL' || anything === 'INFO';\n}\n\n/** Remove trailing slash from a path, if it exists. */\nexport const removeTrailingSlash = (path: string): string => {\n return path.replace(/\\/$/g, '');\n};\n\n/** Take a time in seconds and return a value that represents a time in milliseconds, rounded to the nearest integer */\nexport const calculateTime = (timeInSeconds: number) => Math.round(timeInSeconds * 1000);\n\n/** Same as {@link calculateTime} but if time is \"nullish\", then the return value is `undefined` */\nexport const calculateTimeWithUndefined = (timeInSeconds: number | null | undefined): number | undefined => {\n if (isNullish(timeInSeconds)) {\n return undefined;\n }\n return calculateTime(timeInSeconds);\n};\n\n/**\n * @deprecated Use directly `Date.now()` instead\n *\n * Return the current time in milliseconds.\n */\nexport const getCurrentTimestamp = (): number => {\n return Date.now();\n};\n\n/**\n * Empty function returns undefined\n *\n * @deprecated\n */\nexport const noOp = () => undefined;\n\nexport const getCustomDataString = (customData: any): string | undefined => {\n if (typeof customData === 'object') {\n return tryJSONStringify(customData);\n } else if (isFunction(customData)) {\n return getCustomDataString(customData());\n } else if (typeof customData === 'undefined') {\n return customData;\n } else if (typeof customData !== 'string') {\n return String(customData);\n }\n\n return customData;\n};\n\nexport const transferCustomDataFields = (fromConfig: CustomDataValues, toConfig: CustomDataValues) => {\n for (let i = 1; i <= CustomDataUtils.customDataFieldCount; i++) {\n const customDataField = `customData${i}`;\n toConfig[customDataField] = getCustomDataString(fromConfig[customDataField]);\n }\n};\n\n/**\n * Determine if the page was loaded in the foreground or background\n */\nexport function getPageLoadType(): PAGE_LOAD_TYPE {\n if (isDocumentHidden()) {\n return PAGE_LOAD_TYPE.BACKGROUND;\n }\n return PAGE_LOAD_TYPE.FOREGROUND;\n}\n\nexport const calculatePercentage = (numerator?: number, denominator?: number): number | undefined => {\n if (denominator === undefined || denominator === 0) {\n return undefined;\n }\n return Math.round(((numerator || 0) / denominator) * 100);\n};\n\nexport const getURLResourceName = (url: string): string => {\n if (url.length === 0) {\n return '';\n }\n return url.split('/').pop() || '';\n};\n\nexport const joinUrls = (...args: string[]): string => {\n return args.reduce((prev, current) => {\n const prevUrlValue = endsWith(prev, '/') && current !== undefined ? prev.substr(0, prev.length - 1) : prev;\n const nextUrlValue = startsWith(current, '/') ? current.substr(1) : current;\n return prevUrlValue + '/' + nextUrlValue;\n });\n};\n\n/**\n * Detect if running in a React Native environment using navigator.product\n * https://github.com/facebook/react-native/commit/3c65e62183ce05893be0822da217cb803b121c61\n * https://github.com/facebook/react-native/issues/1331\n * https://stackoverflow.com/questions/39468022/how-do-i-know-if-my-code-is-running-as-react-native\n * navigator object from vega os simulator {\"product\":\"ReactNative\",\"userAgent\":\"ReactNative\"}\n */\nexport const isReactNative = (): boolean => {\n return getGlobalNavigatorProduct() === 'ReactNative';\n};\n\n/**\n * Determine if the audio is muted based on the player muted state and current volume.\n *\n * @param playerIsMuted `true` means muted and `false` means not muted.\n * @param playerVolume A double values must fall between 0 and 1, where 0 is effectively muted and 1 is the loudest possible value.\n */\nexport const isAudioMuted = (playerIsMuted: boolean, playerVolume: number) => {\n /** Audio volume below this delta is considered zero. */\n const VOLUME_DELTA = 0.01;\n\n return playerIsMuted || playerVolume < VOLUME_DELTA;\n};\n\nexport const tryJSONStringify = (obj: unknown): string | undefined => {\n if (isNullish(obj)) {\n return undefined;\n }\n\n try {\n return JSON.stringify(obj);\n } catch {\n return undefined;\n }\n};\n\n/**\n * Checks if a value is an `ArrayBuffer` instance.\n *\n * Uses `Object.prototype.toString` for reliable detection across different\n * execution contexts (e.g. iframes, workers) where `instanceof ArrayBuffer` may fail.\n *\n * @returns {value is ArrayBuffer} `true` if the value is an `ArrayBuffer`, otherwise `false`.\n */\nexport function isArrayBuffer(value: unknown): value is ArrayBuffer {\n return Object.prototype.toString.call(value) === '[object ArrayBuffer]';\n}\n","declare global {\n /** Variable is defined by webpack.DefinePlugin during the build process. */\n const __VERSION__: string;\n}\n\nexport const VERSION: string = __VERSION__;\n","import {addDocumentEventListener, getDocumentPropertyWithPrefix, removeDocumentEventListener} from './documentUtils';\nimport {globalScope} from './globalScope';\nimport {logger} from './Logger';\nimport {isValidString} from './stringUtils';\nimport {isNullish} from './Utils';\n\nexport class ViewportTracker {\n private onIntersectionChanged: () => void;\n private observer?: IntersectionObserver;\n private element: HTMLElement;\n private inViewport?: boolean = undefined;\n private threshold: number;\n private hiddenPropertyName: string | undefined;\n private visibilityChange?: string;\n\n constructor(element: HTMLElement, onIntersectionChanged: () => void, threshold = 1.0) {\n this.threshold = threshold;\n this.onIntersectionChanged = onIntersectionChanged;\n this.element = element;\n\n try {\n const options: IntersectionObserverInit = {\n root: null,\n rootMargin: '0px',\n threshold,\n };\n this.observer = new IntersectionObserver((entries, observer) => this.handleIntersect(entries, observer), options);\n this.observer.observe(element);\n } catch (_error) {\n logger.log(\"Couldn't create instance of IntersectionObserver. timeInViewport will always be reported as 100%.\");\n }\n\n this.hiddenPropertyName = getDocumentPropertyWithPrefix('hidden');\n if (this.hiddenPropertyName) {\n this.visibilityChange = this.hiddenPropertyName.replace('hidden', '') + 'visibilitychange';\n addDocumentEventListener(\n this.visibilityChange,\n (this.handleVisibilityChange = this.handleVisibilityChange.bind(this)),\n false,\n );\n }\n }\n\n isHidden() {\n if (isNullish(globalScope.document) || !isValidString(this.hiddenPropertyName)) {\n return false;\n }\n\n return globalScope.document[this.hiddenPropertyName] === true;\n }\n\n isInViewport(): boolean {\n return !this.isHidden() && (isNullish(this.inViewport) ? true : this.inViewport);\n }\n\n dispose() {\n if (this.observer) {\n this.observer.unobserve(this.element);\n this.observer.disconnect();\n }\n if (this.visibilityChange) {\n removeDocumentEventListener(this.visibilityChange, this.handleVisibilityChange, false);\n }\n }\n\n private handleVisibilityChange() {\n this.onIntersectionChanged();\n }\n\n private handleIntersect(entries: IntersectionObserverEntry[], _observer: IntersectionObserver) {\n entries.forEach((i) => {\n if (i.target === this.element) {\n this.inViewport = !(i.intersectionRatio < this.threshold);\n }\n });\n this.onIntersectionChanged();\n }\n}\n","import {getGlobalWebOSApi} from './globalScopeUtils';\nimport {isBlank, isValidString} from './stringUtils';\n\n// Declaration merging to extend the Window interface with WebOS API\n// see: https://webostv.developer.lge.com/develop/references/webostvjs-webos\ndeclare global {\n interface Window {\n /**\n * @deprecated In webOS TV 4.x or lower, only PalmSystem is supported, and in webOS TV 5.0 or higher,\n * both PalmSystem and webOSSystem are supported. Although PalmSystem is still supported for backward compatibility,\n * future support is not guaranteed so it is strongly recommended that you use webOSSystem in webOS TV 5.0 or higher.\n *\n * @see https://webostv.developer.lge.com/develop/guides/app-lifecycle-management\n */\n PalmSystem?: {\n deviceInfo?: string;\n };\n\n /**\n * Represents the current system interface that should be used on webOS TV 5.0 or higher.\n *\n * @see https://webostv.developer.lge.com/develop/references/webostvjs-webos\n */\n webOSSystem?: {\n /**\n * @see https://webostv.developer.lge.com/develop/references/webostvjs-webos#deviceinfo\n */\n deviceInfo?: string;\n };\n }\n}\n\ntype WebOSDeviceInfo = {modelName: string};\n\nexport function getWebOSTVModelName(): string | undefined {\n try {\n const {webOSSystem, PalmSystem} = getGlobalWebOSApi();\n const info: WebOSDeviceInfo | undefined = webOSSystem?.deviceInfo\n ? JSON.parse(webOSSystem.deviceInfo)\n : PalmSystem?.deviceInfo && JSON.parse(PalmSystem.deviceInfo);\n if (isValidString(info?.modelName) && !isBlank(info?.modelName)) {\n return info.modelName;\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n","import {addGlobalEventListener, removeGlobalEventListener} from './globalScopeUtils';\n\ninterface EventListener {\n eventName: string;\n func: EventListenerOrEventListenerObject;\n}\n\nexport class WindowEventTracker {\n private trackedObjects: EventListener[] = [];\n\n addEventListener(eventName: string, func: EventListenerOrEventListenerObject) {\n this.trackedObjects.push({eventName, func});\n addGlobalEventListener(eventName, func);\n }\n\n release() {\n while (this.trackedObjects.length !== 0) {\n const obj = this.trackedObjects.pop();\n if (obj === undefined) {\n continue;\n }\n\n removeGlobalEventListener(obj.eventName, obj.func);\n }\n }\n}\n","import type {AnalyticsConfig, CollectorConfig} from '../types/AnalyticsConfig';\nimport {extractCustomDataFieldsOnly} from '../types/CustomDataValues';\nimport type {Sample} from '../types/Sample';\nimport type {SourceMetadata} from '../types/SourceMetadata';\n\nimport {getGlobalLocationHostname} from './globalScopeUtils';\nimport {logger} from './Logger';\nimport {isBlank, isValidString} from './stringUtils';\nimport * as Utils from './Utils';\nimport {isFunction, isNotNullish, isNullish} from './Utils';\n\n/**\n * Sanitize {@link AnalyticsConfig} to not be null/undefined\n *\n * Why we return the same config (same reference) passed to function as an argument?\n * Because in the past, we made a mistake and forget to prevent changing `AnalyticsConfig` vie kept reference\n * from outside. Now our customers are using this bug/feature, and we need to keep it for backward compatibility.\n * This should be fixed and changed in the future major release as part of `Collector API v3` changes.\n *\n * @returns A new empty config `{}`, if it was `null/undefined`, otherwise the same config (same reference).\n *\n */\nexport function sanitizeAnalyticsConfig(config: AnalyticsConfig | null | undefined): AnalyticsConfig {\n if (isNullish(config)) {\n return {};\n }\n\n if (!Utils.isBoolean(config.isLive)) {\n config.isLive = undefined;\n }\n\n if (isNotNullish(config.config) && isNotNullish(config.config.errorTransformerCallback)) {\n if (!isFunction(config.config!.errorTransformerCallback!.transform)) {\n config.config.errorTransformerCallback = undefined;\n }\n }\n\n return config;\n}\n\n/**\n * Log error with {@link logger}, if the new configuration is missing `title` property, but old configuration had one.\n */\nexport function guardConfigChangeAgainstMissingTitle(oldConfig: AnalyticsConfig, newConfig: AnalyticsConfig) {\n if (isNullish(oldConfig) || isNullish(newConfig)) {\n // handle undefined values even when argument type does not specify them\n // (defensive approach, because of old code from past and step by step refactorings)\n return;\n }\n\n if (oldConfig.title && isBlank(newConfig.title)) {\n logger.error('The new analytics configuration does not contain the field `title`');\n }\n}\n\n/**\n * Log error with {@link logger}, if the new configuration is missing `isLive` property, but old configuration had one.\n */\nexport function guardConfigChangeAgainstMissingIsLive(oldConfig: AnalyticsConfig, newConfig: AnalyticsConfig) {\n if (isNullish(oldConfig) || isNullish(newConfig)) {\n // handle undefined values even when argument type does not specify them\n // (defensive approach, because of old code from past and step by step refactorings)\n return;\n }\n\n if (oldConfig.isLive && isNullish(newConfig.isLive)) {\n logger.error(\n 'The new analytics configuration does not contain the field `isLive`. It will default to `false` which might be unintended? Once stream playback information is available the type will be populated.',\n );\n }\n}\n\n/**\n * Log warning with {@link logger}, if both `customUserId` and `userId` are set in the configuration.\n */\nexport function guardAgainstDuplicatedUserId(config: AnalyticsConfig) {\n if (isNullish(config)) {\n // handle undefined values even when argument type does not specify them\n // (defensive approach, because of old code from past and step by step refactorings)\n return;\n }\n\n if (isNotNullish(config.customUserId) && isNotNullish(config.userId)) {\n logger.warn(\n 'Configuration Warning: \\n' +\n 'CustomUserId and UserId are set in the config \\n' +\n 'Value of UserId will be used in sample \\n' +\n 'Please only use one configuration field to set your userId',\n );\n }\n}\n\nexport function getDeviceInformationFromAnalyticsConfig(\n config: AnalyticsConfig,\n): Sample['deviceInformation'] | undefined {\n if (isNullish(config)) {\n // handle undefined values even when argument type does not specify them\n // (defensive approach, because of old code from past and step by step refactorings)\n return undefined;\n }\n\n const deviceInformation: Sample['deviceInformation'] = {};\n\n if (isValidString(config.deviceType) && !isBlank(config.deviceType)) {\n // we are using `deviceInformation.model` field to pass `config.deviceType`, because of ingress\n // and how deviceInformation processing is implemented there.\n deviceInformation.model = config.deviceType;\n }\n\n if (isValidString(config.deviceClass) && !isBlank(config.deviceClass)) {\n deviceInformation.deviceClass = config.deviceClass;\n }\n\n if (Object.keys(deviceInformation).length === 0) {\n return undefined;\n }\n\n return deviceInformation;\n}\n\n/**\n * Get {@link CollectorConfig} `origin` field (if any), otherwise return sanitized hostname.\n */\nexport function getDomainFromAnalyticsConfig(config: AnalyticsConfig): string {\n const hostname = getGlobalLocationHostname();\n const fallbackDomain = hostname ? Utils.removeTrailingSlash(hostname) : '';\n return config?.config?.origin ?? fallbackDomain;\n}\n\nfunction removeSourceRelatedFields(config: AnalyticsConfig): AnalyticsConfig {\n const sourceSpecificProperties = ['cdnProvider', 'videoId', 'title', 'isLive', 'experimentName'];\n const customDataFieldsRegex = /customData\\d{1,3}$/g;\n\n for (const key in config) {\n if (isNotNullish(key.match(customDataFieldsRegex)) || sourceSpecificProperties.includes(key)) {\n delete config[key];\n }\n }\n\n return config;\n}\n\nfunction mergeCollectorConfig(\n oldCollectorConfig: CollectorConfig | undefined,\n newCollectorConfig: CollectorConfig | undefined,\n): CollectorConfig {\n if (isNotNullish(newCollectorConfig)) {\n // merging new config should enable the collector by default (unless explicitly disabled in the new config)\n return {...oldCollectorConfig, enabled: true, ...newCollectorConfig};\n }\n return oldCollectorConfig ?? {};\n}\n\nexport function mergeAnalyticsConfig(oldConfig: AnalyticsConfig, newConfig: AnalyticsConfig): AnalyticsConfig {\n const oldConfigWithoutSourceRelatedFields = removeSourceRelatedFields(oldConfig);\n const mergedCollectorConfig = mergeCollectorConfig(oldConfig.config, newConfig.config);\n\n return {\n ...oldConfigWithoutSourceRelatedFields,\n ...newConfig,\n config: mergedCollectorConfig,\n };\n}\n\nexport function applySourceMetadataToAnalyticsConfig(\n config: AnalyticsConfig,\n sourceMetadata: SourceMetadata,\n): AnalyticsConfig {\n let newConfig: AnalyticsConfig = {...config}; // create a new config object to avoid mutating the original one\n\n if (isNotNullish(sourceMetadata.title)) {\n newConfig.title = sourceMetadata.title;\n }\n\n if (isNotNullish(sourceMetadata.videoId)) {\n newConfig.videoId = sourceMetadata.videoId;\n }\n\n if (isNotNullish(sourceMetadata.cdnProvider)) {\n newConfig.cdnProvider = sourceMetadata.cdnProvider;\n }\n\n if (isNotNullish(sourceMetadata.isLive)) {\n newConfig.isLive = sourceMetadata.isLive;\n }\n\n if (isNotNullish(sourceMetadata.customData)) {\n // same style how to set custom data fields like we do in Analytics module\n newConfig = {\n ...newConfig,\n ...extractCustomDataFieldsOnly(sourceMetadata.customData),\n };\n }\n\n return newConfig;\n}\n","import type {AnalyticsConfig} from '../types/AnalyticsConfig';\n\nimport {getDomainFromAnalyticsConfig} from './analyticsConfigUtils';\nimport {logger} from './Logger';\nimport {isBlank} from './stringUtils';\n\n/**\n * Checks if the environment and config is set up correctly to allow proper collector initialization\n * @param config The analytics config to check\n * @returns true if setup is correct and full initialization possible\n */\nexport function areCollectorRequirementsValid(config: AnalyticsConfig): boolean {\n const errorMessages: string[] = [];\n\n // domain available - needed for license calls (authorization)\n const isDomainMissing = isBlank(getDomainFromAnalyticsConfig(config));\n if (isDomainMissing) {\n errorMessages.push(\n 'no `domain` value found (neither from `window.location` object nor provided by `AnalyticsConfig.config.origin`). Without this value, we cannot verify the origin of your analytics data. Please provide the registered domain via the config during collector creation.',\n );\n }\n\n if (errorMessages.length > 0) {\n const fullErrorMessage = 'Collector setup failed:' + errorMessages.join(' -- ');\n logger.errorMessageToUser(fullErrorMessage);\n }\n\n return !isDomainMissing;\n}\n","/**\n * documentUtils provides standalone functions for accessing browser document APIs.\n * This improves testability by allowing easy mocking of document-dependent functionality.\n */\n\nimport {logger} from './Logger';\nimport {isValidString} from './stringUtils';\nimport {isFunction, isNullish} from './Utils';\n\n/**\n * Get a property from document with vendor prefix support\n * Tries the standard property name first, then with webkit/moz/ms/o prefixes\n */\nexport const getDocumentPropertyWithPrefix = (prop: string): string | undefined => {\n if (isNullish(document)) {\n return undefined;\n }\n\n if (prop in document) {\n return prop;\n }\n\n const prefixes = ['webkit', 'moz', 'ms', 'o'];\n const pascalCase = prop.charAt(0).toUpperCase() + prop.slice(1);\n for (const prefix of prefixes) {\n const prefixedProp = prefix + pascalCase;\n if (prefixedProp in document) {\n return prefixedProp;\n }\n }\n\n return undefined;\n};\n\n/**\n * Check if the document is currently hidden (page visibility API)\n */\nexport const isDocumentHidden = (): boolean => {\n const hiddenProp = getDocumentPropertyWithPrefix('hidden');\n if (!isValidString(hiddenProp)) {\n return false;\n }\n\n return document[hiddenProp] === true;\n};\n\n/**\n * Check if a video element is currently in fullscreen mode\n */\nexport const isVideoInFullscreen = (): boolean => {\n const fullscreenProp = getDocumentPropertyWithPrefix('fullscreenElement');\n if (!isValidString(fullscreenProp)) {\n return false;\n }\n\n return document[fullscreenProp]?.nodeName === 'VIDEO';\n};\n\n/**\n * Add event listener to document\n *\n * Use this for document-level events that relate to the DOM structure and document state.\n * Some events ONLY fire on document (not on window):\n * - visibilitychange (& vendor-prefixed variants): tab/page visibility state\n * - fullscreenchange/fullscreenerror: fullscreen mode changes\n * - DOMContentLoaded: DOM parsed and ready (fires before window 'load')\n * - readystatechange: document.readyState changes\n *\n * Important: This function cannot be replaced with window.addEventListener because\n * the above events are document-specific and will not fire on window.\n *\n * We use vendor-prefixed events (webkitvisibilitychange, mozvisibilitychange, etc.)\n * for cross-browser compatibility, especially on older browsers and Smart TVs.\n */\nexport const addDocumentEventListener = (\n event: string,\n handler: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n): void => {\n if (isNullish(document) || !isFunction(document.addEventListener) || isNullish(handler)) {\n return;\n }\n\n // any-wrap needed to not confirm to type checks\n // we use vendor-prefixed events that are not part of the interface\n (document.addEventListener as any)(event, handler, options);\n};\n\n/**\n * Remove event listener from document\n *\n * @see addDocumentEventListener for details on when to use document vs window event listeners\n */\nexport const removeDocumentEventListener = (\n event: string,\n handler: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n): void => {\n if (isNullish(document) || !isFunction(document.removeEventListener) || isNullish(handler)) {\n return;\n }\n\n // any-wrap needed to not confirm to type checks\n // we use vendor-prefixed events that are not part of the interface\n (document.removeEventListener as any)(event, handler, options);\n};\n\n/**\n * Get a cookie value by name\n * @see https://www.w3schools.com/js/js_cookies.asp\n */\nexport const getCookie = (name: string): string | undefined => {\n if (isNullish(document)) {\n return undefined;\n }\n\n let allCookies: string[];\n try {\n allCookies = document.cookie.split(';');\n } catch (_error) {\n logger.log('failed to access cookie objects on document', _error);\n return undefined;\n }\n\n const cookieName = name + '=';\n for (const c of allCookies) {\n let cookie = c;\n while (cookie.charAt(0) === ' ') {\n cookie = cookie.substring(1); // trim spaces (if any) between ';' and next attribute\n }\n if (cookie.indexOf(cookieName) === 0) {\n return cookie.substring(cookieName.length, cookie.length);\n }\n }\n return '';\n};\n\n/**\n * Set a cookie with optional attributes\n */\nexport const setCookie = (\n name: string,\n value: string,\n attributes?: {domain?: string; expires?: string; maxAge?: number},\n): void => {\n if (isNullish(document)) {\n return;\n }\n\n let newCookie = name + '=' + value + '; path=/';\n\n if (attributes?.domain) {\n newCookie += `; domain=${attributes.domain}`;\n }\n\n if (attributes?.expires) {\n newCookie += `; expires=${attributes.expires}`;\n }\n\n if (attributes?.maxAge) {\n newCookie += `; max-age=${attributes.maxAge}`;\n }\n\n try {\n document.cookie = newCookie;\n } catch (_error) {\n logger.log('failed to set cookie object on document', _error);\n return;\n }\n};\n\n/**\n * Delete a cookie by name\n * @see https://www.w3schools.com/js/js_cookies.asp\n */\nexport const deleteCookie = (name: string): void => {\n if (isNullish(document)) {\n return;\n }\n\n try {\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;\n } catch (_error) {\n logger.log('failed to delete cookies from document', _error);\n return;\n }\n};\n","function getGlobalThis(): typeof globalThis {\n // eslint-disable-next-line no-restricted-globals\n if (typeof globalThis !== 'undefined') return globalThis;\n // eslint-disable-next-line unicorn/prefer-global-this\n if (typeof window !== 'undefined') return window as any;\n // eslint-disable-next-line unicorn/prefer-global-this\n if (typeof global !== 'undefined') return global as any;\n // eslint-disable-next-line unicorn/prefer-global-this\n if (typeof self !== 'undefined') return self as any;\n throw new Error('Unable to locate global object');\n}\n\n/**\n * Provides a safe reference to the global object APIs across all environments.\n *\n * `globalThis` is a standard built-in JavaScript object that always refers to the global object of the current\n * environment, regardless of whether your code runs in a browser, Node.js, a worker, or a module.\n *\n * But `globalThis` was introduced in ES2020, and older platforms like Tizen 2016 (Chromium ~2015-2016) do not support\n * it. Rather than bundling a full polyfill into the library, this helper resolves the global object at runtime by\n * checking the available global references in order: `globalThis` → `window` → `global` → `self`.\n *\n * This improves:\n * - compatibility with various environments where the `window` global variable may not be available (VegaOS, React Native)\n * - testability by allowing easy mocking of global object functionality.\n */\nexport const globalScope = getGlobalThis();\n","import {globalScope} from './globalScope';\nimport {isNumber} from './numberUtils';\nimport {isValidString} from './stringUtils';\nimport {isFunction, isNullish} from './Utils';\n\n/**\n * Get `globalScope.devicePixelRatio` (defaults to `1` if not available)\n */\nexport const getGlobalDevicePixelRatio = (): number => {\n if (isNullish(globalScope.devicePixelRatio)) {\n return 1;\n }\n return globalScope.devicePixelRatio > 0 ? globalScope.devicePixelRatio : 1;\n};\n\n/**\n * Get `globalScope.screen` dimensions with {@link getGlobalDevicePixelRatio} applied\n */\nexport const getGlobalScreenDimensions = (): {height: number; scale: number; width: number} | undefined => {\n if (isNullish(globalScope.screen)) {\n return undefined;\n }\n\n if (!isNumber(globalScope.screen.width) || !isNumber(globalScope.screen.height)) {\n return undefined;\n }\n\n const scale = getGlobalDevicePixelRatio();\n const width = globalScope.screen.width * scale;\n const height = globalScope.screen.height * scale;\n\n if (!isFinite(width) || !isFinite(height) || width <= 0 || height <= 0) {\n return undefined;\n }\n\n return {width, height, scale};\n};\n\n/**\n * Add global event listener\n *\n * Use this for window-level events that relate to the browser viewport/tab:\n * - resize: viewport size changes\n * - scroll: page scroll (when listening at window level)\n * - load/unload/beforeunload: page lifecycle\n * - focus/blur: window/tab focus state\n * - hashchange/popstate: navigation events\n * - storage: localStorage changes from other tabs\n *\n * Note: Events bubble up from target → document → window, so window receives\n * many events that also fire on document, but not vice versa.\n */\nexport const addGlobalEventListener = (event: string, handler: EventListenerOrEventListenerObject): void => {\n if (isNullish(globalScope.addEventListener) || !isFunction(globalScope.addEventListener) || isNullish(handler)) {\n return;\n }\n // any-wrap needed to not confirm to type checks\n // we use vendor-prefixed events that are not part of the interface\n globalScope.addEventListener(event, handler);\n};\n\n/**\n * Remove global event listener\n *\n * @see addWindowEventListener for details on when to use window vs document event listeners\n */\nexport const removeGlobalEventListener = (event: string, handler: EventListenerOrEventListenerObject): void => {\n if (\n isNullish(globalScope.removeEventListener) ||\n !isFunction(globalScope.removeEventListener) ||\n isNullish(handler)\n ) {\n return;\n }\n\n // any-wrap needed to not confirm to type checks\n // we use vendor-prefixed events that are not part of the interface\n globalScope.removeEventListener(event, handler);\n};\n\n/**\n * Get `globalScope.location.hostname`\n */\nexport const getGlobalLocationHostname = (): string | undefined => {\n if (isNullish(globalScope.location)) {\n return undefined;\n }\n\n if (!isValidString(globalScope.location.hostname)) {\n return undefined;\n }\n\n return globalScope.location.hostname;\n};\n\n/**\n * Get `globalScope.location.pathname`\n */\nexport const getGlobalLocationPathname = (): string | undefined => {\n if (isNullish(globalScope.location)) {\n return undefined;\n }\n\n if (!isValidString(globalScope.location.pathname)) {\n return undefined;\n }\n\n return globalScope.location.pathname;\n};\n\n/**\n * Get `globalScope.performance.now()` or `undefined` if not available\n *\n * Note: `performance.now()` is preferred over `Date.now()` for measuring time intervals because it provides higher\n * precision and is not affected by changes to the system clock.\n */\nexport const getGlobalPerformanceNow = (): DOMHighResTimeStamp | undefined => {\n if (isNullish(globalScope.performance?.now) || !isFunction(globalScope.performance.now)) {\n return undefined;\n }\n\n // performance.now() returns a DOMHighResTimeStamp, which is a number representing milliseconds with microsecond precision\n return globalScope.performance.now();\n};\n\n/**\n * Get from `global object` the WebOS-specific API objects (for WebOS TV support)\n */\nexport const getGlobalWebOSApi = (): {PalmSystem?: any; webOSSystem?: any} => {\n return {\n webOSSystem: globalScope.webOSSystem,\n PalmSystem: globalScope.PalmSystem,\n };\n};\n\n/**\n * Check if WebOS API is available (for WebOS TV support)\n */\nexport const hasGlobalWebOSApi = (): boolean => {\n const {webOSSystem, PalmSystem} = getGlobalWebOSApi();\n return !isNullish(webOSSystem) || !isNullish(PalmSystem);\n};\n\n/**\n * Get `globalScope.navigator.language` (with fallback to `globalScope.navigator.userLanguage` for IE)\n */\nexport const getGlobalNavigatorLanguage = (): string | undefined => {\n if (isNullish(globalScope.navigator)) {\n return undefined;\n }\n\n return globalScope.navigator.language || (globalScope.navigator as any).userLanguage;\n};\n\n/**\n * Get `globalScope.navigator.product`\n */\nexport const getGlobalNavigatorProduct = (): string | undefined => {\n if (isNullish(globalScope.navigator)) {\n return undefined;\n }\n\n // navigator.product is deprecated, but it remains the standard way to detect some environments like React Native\n return globalScope.navigator.product;\n};\n\n/**\n * Get `globalScope.navigator.userAgent`\n */\nexport const getGlobalNavigatorUserAgent = (): string | undefined => {\n if (isNullish(globalScope.navigator) || !isValidString(globalScope.navigator.userAgent)) {\n return undefined;\n }\n\n return globalScope.navigator.userAgent;\n};\n\n/**\n * Get `globalScope.videojs.VERSION`\n */\nexport const getGlobalVideojsVersion = (): string | undefined => {\n if (isNullish(globalScope.videojs)) {\n return undefined;\n }\n\n return globalScope.videojs['VERSION'];\n};\n\n/**\n * Get `globalScope.THEOplayer.VERSION`\n */\nexport const getGlobalTheoPlayerVersion = (): string | undefined => {\n if (isNullish(globalScope.THEOplayer)) {\n return undefined;\n }\n\n return globalScope.THEOplayer.version;\n};\n","import {isFunction, isNullish} from './Utils';\n\n/**\n * @returns {value is number} `true` if the given value is {@link isNotNullish} and is type of `number`.\n */\nexport const isNumber = (value: unknown): value is number => !isNullish(value) && typeof value === 'number';\n\n/**\n * Checks if a value is a finite number (not NaN, not Infinity, and not -Infinity).\n *\n * This function should be used instead of directly calling `Number.isFinite` or the global `isFinite`\n * because it provides ES5 compatibility and proper type checking.\n *\n * **Why not use `Number.isFinite` directly?**\n * `Number.isFinite` is an ES6 method and does not exist in ES5 environments. Calling it directly\n * would throw a `TypeError` at runtime in older environments.\n *\n * **Key difference between `Number.isFinite` and global `isFinite`:**\n * - `Number.isFinite(value)` does NOT coerce the value — it returns `true` only if the value is\n * already a number and is finite. For example, `Number.isFinite(\"123\")` returns `false`.\n * - Global `isFinite(value)` DOES coerce the value to a number before checking. For example,\n * `isFinite(\"123\")` returns `true` because `\"123\"` is coerced to `123`.\n *\n * This function avoids the coercion risk by first checking the type with `isNumber`, making both\n * implementations behave consistently regardless of the environment.\n *\n * @param value - The value to check\n * @returns `true` if the value is a finite number, `false` otherwise (including NaN, Infinity, -Infinity, null, undefined, or non-numeric types)\n *\n * @example\n * isFiniteNumber(123) // true\n * isFiniteNumber(0) // true\n * isFiniteNumber(-456.78) // true\n * isFiniteNumber(NaN) // false\n * isFiniteNumber(Infinity) // false\n * isFiniteNumber(-Infinity) // false\n * isFiniteNumber(\"123\") // false (string, not coerced)\n * isFiniteNumber(null) // false\n * isFiniteNumber(undefined) // false\n */\nexport const isFiniteNumber = (value: unknown): value is number => {\n if (!isNumber(value)) {\n return false;\n }\n\n // our target is ES5, so we can't use Number.isFinite without checking for it\n if (isFunction(Number.isFinite)) {\n return Number.isFinite(value);\n }\n\n // Fallback implementation for environments that do not support Number.isFinite\n return isFinite(value);\n};\n\n/**\n * Converts a string to an integer using native `parseInt` and returns `undefined` if the result is not a finite number\n */\nexport const parseIntOrUndefined = (value: string): number | undefined => {\n const result = parseInt(value, 10);\n return isFiniteNumber(result) ? result : undefined;\n};\n","import {logger} from './Logger';\n\n/** Polyfill for ES2017 'Object.values' */\nexport const objectValues = (obj: any) => {\n return Object.keys(obj).map(function (key) {\n return obj[key];\n });\n};\n\n/**\n * Wraps property access with try/catch\n */\nexport function safeAccess<T>(access: () => T): T | undefined {\n try {\n return access();\n } catch (error) {\n logger.log(`safeAccess catched failed access on property: `, error);\n return undefined;\n }\n}\n","import {SSAI_RELATED_SAMPLE_MARKER} from '../core/ssai/ssaiUtils';\nimport type {AdSample} from '../types/AdSample';\nimport type {Sample} from '../types/Sample';\n\nimport {getGlobalLocationPathname} from './globalScopeUtils';\nimport {isValidString} from './stringUtils';\nimport * as Utils from './Utils';\nimport {isNullish, removeTrailingSlash} from './Utils';\n\n/**\n * Clear all \"state\" values from the sample (all values that describe \"playing sample\", \"startup sample\" ...).\n */\nexport function clearSampleStateValues(sample: Sample): void {\n sample.ad = 0;\n sample.adId = undefined;\n sample.adIndex = undefined;\n sample.adPosition = undefined;\n sample.adSystem = undefined;\n sample.autoplay = undefined;\n sample.buffered = 0;\n sample.castTech = undefined;\n sample.completed = undefined;\n sample.drmLoadTime = undefined;\n sample.droppedFrames = 0;\n sample.duration = 0;\n sample.errorCode = undefined;\n sample.errorData = undefined;\n sample.errorMessage = undefined;\n sample.errorSegments = undefined;\n sample.errorSeverity = undefined;\n sample.isProgramChange = undefined;\n sample.pageLoadTime = 0;\n sample.paused = 0;\n sample.played = 0;\n sample.playerStartupTime = 0;\n sample.seeked = 0;\n sample.startupTime = 0;\n sample.state = undefined;\n sample.videoStartFailed = undefined;\n sample.videoStartFailedReason = undefined;\n sample.videoStartupTime = 0;\n\n sample[SSAI_RELATED_SAMPLE_MARKER] = undefined;\n}\n\nexport function getDefaultSamplePath(): string | undefined {\n const pathname = getGlobalLocationPathname();\n return isValidString(pathname) ? removeTrailingSlash(pathname) : undefined;\n}\n\nexport function buildAdSample(sample?: Sample): AdSample {\n const adSample: AdSample = {};\n\n if (isNullish(sample)) {\n return adSample;\n }\n\n adSample.cdnProvider = sample.cdnProvider;\n adSample.customUserId = sample.customUserId;\n adSample.domain = sample.domain;\n adSample.key = sample.key;\n adSample.language = sample.language;\n adSample.path = sample.path;\n adSample.player = sample.player;\n adSample.playerKey = sample.playerKey;\n adSample.playerTech = sample.playerTech;\n adSample.screenHeight = sample.screenHeight;\n adSample.screenWidth = sample.screenWidth;\n adSample.size = sample.size;\n adSample.userAgent = sample.userAgent;\n adSample.userId = sample.userId;\n adSample.version = sample.version;\n adSample.videoId = sample.videoId;\n adSample.videoImpressionId = sample.impressionId;\n adSample.videoTitle = sample.videoTitle;\n adSample.videoWindowHeight = sample.videoWindowHeight;\n adSample.videoWindowWidth = sample.videoWindowWidth;\n\n Utils.transferCustomDataFields(sample, adSample);\n adSample.experimentName = sample.experimentName;\n\n return adSample;\n}\n","import {isFunction, isNotNullish, isNullish} from './Utils';\n\nexport const isValidString = (s: unknown): s is string => isNotNullish(s) && typeof s === 'string';\n\nexport const isEmpty = (s: string | null | undefined): boolean => isNullish(s) || s.length === 0;\n\nexport const isBlank = (s: string | null | undefined): boolean => isEmpty(s) || isEmpty(s?.trim());\n\nexport const endsWith = (s: string, suffix: string): boolean => {\n if (!isValidString(s) || !isValidString(suffix)) {\n return false;\n }\n\n // our target is ES5, so we can't use String.prototype.endsWith without checking for it\n if (isFunction(String.prototype.endsWith)) {\n return s.endsWith(suffix);\n }\n\n // Fallback implementation for environments that do not support String.prototype.endsWith\n return s.substring(s.length - suffix.length) === suffix;\n};\n\nexport const startsWith = (s: string, prefix: string): boolean => {\n if (!isValidString(s) || !isValidString(prefix)) {\n return false;\n }\n\n // our target is ES5, so we can't use String.prototype.startsWith without checking for it\n if (isFunction(String.prototype.startsWith)) {\n return s.startsWith(prefix);\n }\n\n // Fallback implementation for environments that do not support String.prototype.startsWith\n return s.substring(0, prefix.length) === prefix;\n};\n","export const generateUUID = (): string => {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","import {BitmovinPwxAnalyticsPackage} from './adapters/bitmovinPwx/BitmovinPwxAnalyticsPackage';\nimport {CdnProvider} from './enums/CDNProvider';\nimport {Player} from './enums/Player';\nimport {VERSION} from './utils/Version';\n\nexport {VERSION as version};\n\nexport type {AnalyticsConfig} from './types/AnalyticsConfig';\n\nexport {Player as Players};\nexport {CdnProvider as CdnProviders};\n\nexport {BitmovinPwxAnalyticsPackage};\n"],"names":["root","factory","exports","module","define","amd","self","StateMachine","VERSION","Result","SUCCEEDED","NOTRANSITION","CANCELLED","PENDING","Error","INVALID_TRANSITION","PENDING_TRANSITION","INVALID_CALLBACK","WILDCARD","ASYNC","create","cfg","target","initial","state","terminal","fsm","events","callbacks","map","transitions","add","e","from","Array","isArray","name","n","length","push","to","event","hasOwnProperty","buildEvent","current","is","indexOf","this","can","transition","undefined","cannot","concat","isFinished","error","args","msg","states","Object","keys","sort","defer","doCallback","func","apply","beforeAnyEvent","afterAnyEvent","leaveAnyState","enterAnyState","changeState","beforeThisEvent","afterThisEvent","leaveThisState","enterThisState","beforeEvent","afterEvent","leaveState","specific","general","enterState","prototype","slice","call","arguments","cancel","leave","context","config","getCurrentImpressionId","analytics","getUserId","setCustomData","values","internalAdapter","setCustomDataOnce","sourceChange","_config","sanitizedConfig","sanitizeAnalyticsConfig","areCollectorRequirementsValid","guardAgainstDuplicatedUserId","BitmovinPwxInternalAdapter","Analytics","dispose","release","version","BitmovinPwxAdapter","onAdd","dependencies","BitmovinPwxAnalyticsPackage","_","baseContext","registry","get","CoreExportNames","CoreEffects","EventListenerEffectFactory","StateEffectFactory","using","logger","BundleExportNames","Logger","source","SourceExportNames","SourceState","playerConfig","PlayerConfig","analyticsConfig","playerKey","key","log","tryJSONStringify","adapter","url","listener","abortSignal","removeEventListener","addEventListener","Constants","CoreStateAtoms","SourcesApiExportNames","SourceEventBus","PlaybackApiEventsPackageExportNames","PlaybackEvent","_name","State","stateMachineCallbacks","playingHeartbeatService","opts","enabledDebugging","debuggingStates","createStateMachine","SETUP","JSM_INITIAL_EVENT","customStateMachineErrorCallback","Event","SOURCE_LOADED","ERROR","READY","on","stayIn","PAUSE","TIMECHANGED","PLAY","STARTUP","PLAYING","END","VIDEOSTART_FAILED","getAllStatesBut","UNLOAD","stopHeartbeat","onleavestate","eventTimestamp","eventData","logStateMachineTransition","addStatesToLog","stateDuration","onEnterStateTimestamp","isStartup","maybeSetOrClearVideoStartTimeouts","startup","toLowerCase","lowerCaseFrom","String","unload","setup","clearVideoStartTimeout","defaultStateMachineCallbackFn","isFunction","logMissingCallbackWarning","startHeartbeat","onenterstate","_eventData","Date","now","isNumber","starttime","_event","_from","_to","_eventTimestamp","timestamp","eventObject","EventDebugging","getStates","setEnabledDebugging","enabled","setVideoStartTimeout","AnalyticsStateMachine","BitmovinPwxAnalyticsStateMachine","onBeforeUnLoadEvent","HeartbeatService","currentTime","stateMachine","setListener","getSource","playback","playhead","position","getAutoPlay","autoplay","getCurrentPlaybackInfo","hls","sourceConfig","resources","filter","v","includes","dash","videoRect","video","element","getBoundingClientRect","videoWidth","Math","round","width","videoHeight","height","streamFormat","StreamTypes","getCommonPlaybackInfo","droppedFrames","isMuted","muted","isLive","stream","type","videoWindowHeight","videoWindowWidth","videoDuration","normalizeVideoDuration","duration","videoPlaybackHeight","videoPlaybackWidth","m3u8Url","mpdUrl","videoCodec","audioCodec","videoBitrate","audioBitrate","getPlayerName","Player","BITMOVIN_PWX","getPlayerTech","getPlayerVersion","Version","initialize","registerEventListeners","registerUnloadEventListeners","ErrorDetailTracking","errorDetailTrackingSettingsProvider","ErrorDetailBackend","collectorConfig","errorDetailSubscribable","handleCollectorUnload","eventCallback","bind","windowEventTracker","sourceEventBus","playbackAtom","Ready","Play","Playing","Paused","TimeChanged","VideoAttached","Ended","abortListener","abortSignalReason","reason","SOURCE_UNLOADED","code","message","data","originalError","InternalAdapter","Utils","CreateSourceStateAtom","CreateSourceReference","SourceReferences","SourceApiManager","VideoElementUtils","onLicenseKeyReceived","EventDispatcher","onLicenseCallFailed","qualityChangeService","ssaiService","SsaiService","defaultStateMachineCallbacks","sourceInfoFallbackService","SourceInfoFallbackService","drmPerformanceInfo","WindowEventTracker","getCurrentTimestamp","resetIntervals","resetSourceRelatedState","callEvent","dimensions","getGlobalScreenDimensions","screenHeight","screenWidth","getDrmPerformanceInfo","getSegmentInfo","getDownloadSpeedInfo","segmentsDownloadCount","segmentsDownloadSize","segmentsDownloadTime","avgDownloadSpeed","minDownloadSpeed","maxDownloadSpeed","avgTimeToFirstByte","resetDownloadSpeedInfoMeasures","previousState","currentState","customDataValues","customdatachange","CUSTOM_DATA_CHANGE","MANUAL_SOURCE_CHANGE","reset","programChange","sourceMetadata","isSsaiActive","isInActiveState","AdQuartile","onAdStarted","_ad","onAdFinished","onAdBreakStarted","_adBreak","onAdBreakFinished","onAdClicked","onAdError","onAdManifestLoaded","onAdQuartile","onAdSkipped","onPlay","onPause","onBeforeUnload","AdCallbacks","BUFFERING_HEARTBEAT_INTERVALS","videoStartupTimeoutMs","Settings","ANALYTICS_VIDEOSTART_TIMEOUT","bufferTimeoutMs","ANALYTICS_BUFFER_TIMEOUT","currentBufferingIntervalIndex","stateMachineEventMethod","warn","clearBufferingTimeoutHandle","clearBufferingHeartbeatHandle","startBufferingHeartbeatInterval","resetBufferingHelpers","startBufferingTimeoutHandle","bufferingHeartbeatIntervalHandle","setInterval","getTime","heartbeat","buffered","min","isNotNullish","clearInterval","bufferingTimeoutHandle","setTimeout","ErrorCode","BUFFERING_TIMEOUT_REACHED","additionalData","clearTimeout","videoStartTimeout","VIDEOSTART_TIMEOUT","onHeartbeat","playerCurrentTime","sendPlayingSample","triggeredBySsai","triggeredByProgramChange","setVideoTimeEndFromEvent","payload","played","isProgramChange","SSAI_RELATED_SAMPLE_MARKER","resetCurrentStateStart","stateEnterTimestamp","setVideoTimeStartFromEvent","programChangeTimestamp","updateSourceMetadata","excludedStates","stateEnumObj","getAllStates","s","whileIn","stateMachineEventDefBuilderFn","runEventCallbacksFor","passOver","eventName","errorCode","errorMessage","_ex","loggerMessage","loggerMessageData","ignoreStates","isNullish","find","ignoredState","stateStringEnumObj","objectValues","padRight","isPlaying","adPodPosition","adCallbacks","container","getContainer","viewportTracker","ViewportTracker","onIntersectionChanged","clearCurrentTimeInterval","adManifestDownloadTime","activeAdState","isContainerInViewport","enterViewportTimestamp","timeInViewport","isInViewport","isLinearAdActive","beginPlayingTimestamp","updatePlayingTime","isVmap","sendAnalyticsRequest","buildInitialActiveAdBreakState","adBreakInfo","manifestDownloadTime","adBreak","activeAdBreakState","adStartupTimestamp","resetActiveAd","adInfo","isLinear","buildInitialActiveAdState","adStartupTime","startAd","activeAdStateCopy","completed","completeAd","adDuration","skipped","skipPosition","skipPercentage","calculatePercentage","exitPosition","adBreakSample","transformedError","transformError","severity","errorData","errorSeverity","activeAdId","adId","errorPosition","errorPercentage","adClickthroughUrl","clickThroughUrl","clicked","clickPosition","clickPercentage","quartile","FIRST_QUARTILE","quartile1","MIDPOINT","midpoint","THIRD_QUARTILE","quartile3","closed","closePosition","closePercentage","adSample","buildAdSample","sample","moduleInfo","getAdModuleInfo","platform","analyticsVersion","adModule","adModuleVersion","pageLoadType","getPageLoadType","time","adImpressionId","generateUUID","percentageInViewport","timePlayed","backend","sendAdRequest","started","currentTimeInterval","calculateTime","max","AdAnalytics","TIMEOUT_CURRENT_TIME_INTERVAL","playPercentage","MODULE_NAME","adFallbackIndex","adIdPlayer","id","adReplaceContentDuration","calculateTimeWithUndefined","replaceContentDuration","adIsPersistent","persistent","adTagType","tagType","adTagUrl","tagUrl","adPreloadOffset","preloadOffset","fallbackIndex","adPosition","adOffset","URL","adTagServer","hostname","adTagPath","pathname","isFiniteNumber","scheduleTime","adScheduleTime","mediaUrl","adPlaybackHeight","adPlaybackWidth","mimeType","mediaPath","mediaServer","bitrate","vastData","adSystem","advertiserName","apiFramework","creativeAdId","creativeId","universalAdIdRegistry","universalAdIdValue","adDescription","minSuggestedDuration","surveyUrl","adTitle","wrapperAdsCount","skippableAfter","adSkipAfter","adSkippable","skippable","initialAnalyticsConfig","backendFactory","sessionHandler","featureManager","onErrorDetailEventDispatcher","identicalErrorReportingLimiter","hasSentStartupSample","droppedSampleFrames","playerStartupTime","authenticationCallback","authenticationCompleted","success","featureConfigs","configureFeatures","guardConfigChangeAgainstMissingTitle","guardConfigChangeAgainstMissingIsLive","newConfig","mergeAnalyticsConfig","oldConfig","setState","sendSample","setConfigParameters","setAutoDetectedDeviceInformation","impressionId","userId","changeCustomData","extractCustomDataFieldsOnly","SessionPersistenceHandler","that","domain","getDomainFromAnalyticsConfig","licenseKey","licenseKeyReceivedUnsubscriber","subscribe","eventArgs","buildInitialSample","init","setupStateMachineCallbacks","features","registerFeatures","adAnalytics","supportsDeferredLicenseLoading","isValidString","isBlank","debug","resetFeatures","createBackend","videoCompletionTracker","resetValues","errorMessageToUser","player","deviceInformation","getDeviceInformationFromAnalyticsConfig","cdnProvider","videoId","videoTitle","title","customUserId","transferCustomDataFields","experimentName","model","hasGlobalWebOSApi","modelName","getWebOSTVModelName","setDuration","navigationStart","globalScope","performance","timing","pageLoadTime","supportedVideoCodecs","CodecHelper","supportedVideoFormats","sanitizeVideoStartupTime","videoStartupTime","startupTime","drmPerformance","drmType","drmLoadTime","setStartupHasFinished","applySourceMetadataToAnalyticsConfig","path","getDefaultSamplePath","playing","setCompletionValues","videoStartForClosedState","videoTimeStart","videoTimeEnd","sendUnloadRequest","clearSampleStateValues","setVideoTimeStart","setVideoTimeEnd","heartbeatPayload","qualitychange","startResetInterval","increaseCounter","hasExceededQualityChangeThreshold","QUALITY_CHANGE_THRESHOLD_EXCEEDED","legacyData","updateSampleQualityInfo","codec","audiotrack_changing","pause","paused","seeking","seeked","buffering","videoStartFailed","videoStartFailedReason","VideoStartFailedReason","PLAYER_ERROR","TIMEOUT","VIDEO_STARTUP_TIMEOUT_REACHED","dispatch","shouldReportError","errorSegments","onError","ad","AD_TYPE","CSAI","mute","unMute","subtitle_changing","analyticsEventBase","manualSourceChange","initialSourceChange","end","NoOpBackend","stopResetInterval","_duration","_state","setPlaybackInfoFromAdapter","info","size","playerTech","progUrl","isBoolean","isCasting","castTech","audioLanguage","subtitleEnabled","subtitleLanguage","customDataOnceValues","downloadSpeedInfo","manipulate","setQualityInfoOnSample","copySample","sendRequest","sendSsaiEngagementAdSample","ssaiEngagementTrackingEnabled","isSsaiEngagementStartedData","ssaiAdSample","createStartedAdSample","isSsaiEngagementQuartileData","createQuartileAdSample","isSsaiEngagementErrorData","analyticsError","ssaiErrorAdSample","createErrorAdSample","addWatched","start","completedTotal","getCompletionPercentage","Number","isNaN","value","errorTransformerCallback","transform","isErrorSeverity","screenDimensions","language","getGlobalNavigatorLanguage","PlayerSize","Window","userAgent","getGlobalNavigatorUserAgent","BackendFactory","FeatureManager","IdenticalErrorReportingLimiter","playbackInfo","licensingRequest","isEnabled","inner","createInnerBackend","decorateWithDebuggingBackend","DebuggingBackend","decorateWithBackendFromConfigIfAvailable","innerBackend","wrapBackend","backendUrl","ANALYTICS_BACKEND_BASE_URL","LicenseCheckingBackend","LicenseCall","sequenceNumberAssigningBackend","SequenceNumberBackend","LongPlaytimeFilteringBackend","underlying","fields","debugFields","printFields","forEach","f","table","callback","unsubscribe","index","splice","DEFAULT_HEARTBEAT_INTERVAL_MS","getPlayerCurrentTime","heartbeatInterval","clearHeartbeat","_currentErrorCount","_lastErrorCode","_lastErrorSeverity","MAX_IDENTICAL_ERROR_REPORTING","licenseCall","backendBaseUrl","licenseKeyReceived","licenseLazyLoadingTimeoutHandle","unsubscribeFromAdapter","promise","wrapLicenseCheckPromiseWithCallback","performLicenseCheck","licenseCallFailed","licenseLazyLoadingTimeout","QueueBackend","ANALYTICS_LICENSECALL_TIMEOUT","status","LicensingResult","Denied","Promise","resolve","then","result","Granted","remoteBackend","RemoteBackend","flushTo","catch","err","response","next","nextBackend","isPlayedAboveThreshold","_sample","_adSample","qualityChangeCountThreshold","ANALYTICS_QUALITY_CHANGE_COUNT_THRESHOLD","qualityChangeCount","previousVideoBitrate","previousAudioBitrate","startupHasFinished","QUALITY_CHANGE_COUNT_THRESHOLD","startupVideoBitrate","startupAudioBitrate","shouldAllowVideoQualityChange","newBitrate","setVideoBitrate","shouldAllowAudioQualityChange","setAudioBitrate","qualityChangeCountResetIntervalId","ANALYTICS_QUALITY_CHANGE_COUNT_RESET_INTERVAL","queue","unloadQueue","adQueue","analyticsCall","AnalyticsCall","sequenceNumber","updateSampleBeforeSending","isSequenceNumberAboveThreshold","SEQUENCE_NUMBER_LIMIT","COOKIE_NAME_BITMOVIN_ANALYTICS_UUID","COOKIE_DEFAULT_MAX_AGE","cookiesEnabled","deleteCookie","existingUserId","getCookie","cookieDomain","validateCookieDomainValue","cookiesDomain","cookieMaxAge","validateCookieMaxAgeValue","cookiesMaxAge","nowMillis","cookieExpires","toUTCString","setCookie","expires","maxAge","encodeURIComponent","setStreamFormat","applyStreamFormat","applyAndStoreCodecInfo","codecInfo","SsaiState","eventHandler","adIndex","IDLE","isFirstSampleOfAd","sentAdQuartiles","errorSent","activate","adBreakStart","adBreakMetadata","isActivated","AD_BREAK_STARTED","currentAdMetadata","adStart","adMetadata","reportPlaybackInteraction","ACTIVE","resetAdData","customData","currentAdImpressionId","timestampOfAdStart","getCurrentMonotonicTimestampInMs","reportEngagementInteraction","adQuartileFinished","adQuartile","adQuartileMetadata","quartileMetadata","timeSinceAdStartedInMs","getMonotonicTimestampInMsSince","adBreakEnd","resetAdBreakData","SSAI","customDataValuesKeys","sendAdEngagementErrorSample","adType","ROUTING_URL_PARAM","ROUTING_URL_PARAM_VALUE_SSAI","playbackSample","ssaiEngagementErrorData","ssaiEngagementStartedData","ssaiEngagementQuartileData","timestampInMs","adEngagementSample","customData1","customData2","customData3","customData4","customData5","customData6","customData7","customData8","customData9","customData10","customData11","customData12","customData13","customData14","customData15","customData16","customData17","customData18","customData19","customData20","customData21","customData22","customData23","customData24","customData25","customData26","customData27","customData28","customData29","customData30","customData31","customData32","customData33","customData34","customData35","customData36","customData37","customData38","customData39","customData40","customData41","customData42","customData43","customData44","customData45","customData46","customData47","customData48","customData49","customData50","customData51","customData52","customData53","customData54","customData55","customData56","customData57","customData58","customData59","customData60","customData61","customData62","customData63","customData64","customData65","customData66","customData67","customData68","customData69","customData70","customData71","customData72","customData73","customData74","customData75","customData76","customData77","customData78","customData79","customData80","customData81","customData82","customData83","customData84","customData85","customData86","customData87","customData88","customData89","customData90","customData91","customData92","customData93","customData94","customData95","customData96","customData97","customData98","customData99","customData100","videoImpressionId","quartile1FailedBeaconUrl","failedBeaconUrl","midpointFailedBeaconUrl","quartile3FailedBeaconUrl","completedFailedBeaconUrl","performanceNow","getGlobalPerformanceNow","floor","CdnProvider","BITMOVIN_PLAYER_LICENSING_ERROR","SETUP_MISSING_LICENSE_WHITELIST","urlPath","split","endsWith","MIMETypes","HLS","MP4","WEBM","DASH","PAGE_LOAD_TYPE","prog","stateMachineEvent","PAGE_CLOSED","UNKNOWN","_isEnabled","disable","disabled","configure","authenticated","configContainer","extractConfig","configured","Feature","unregisterFeatures","feature","constructor","_queue","_enabled","joinUrls","copyErrorDetailTruncateStringsAndUrls","errorDetail","maxStringLength","maxUrlLength","substr","copyErrorDataTruncateStrings","httpRequests","request","copyHttpRequestTruncateUrls","httpRequest","maxLength","lastRedirectLocation","exceptionMessage","copyErrorDetailTruncateHttpRequests","maxRequests","limitHttpRequestsOfQueuedErrorDetails","send","errorDetailCopy","MAX_STRING_LENGTH","MAX_URL_LENGTH","post","flush","copy","shift","removeFromQueue","clear","findIndex","settingsProvider","subscribables","httpRequestTracking","errorIndex","onErrorHandler","httpRequestsCopy","errorId","exceptionStacktrace","subscribable","_authenticated","numberOfHttpRequests","errorDetails","customDataFieldCount","i","match","input","retVal","sanitizeCustomDataValues","extracted","sanitizedCustomDataValues","getCustomDataString","playerVideoDuration","Infinity","streamType","streamUrl","DEFAULT_RESULT","startCasting","casting","muting_ready","baseUrl","analyticsServerUrl","adAnalyticsServerUrl","analyticsUrl","isSsaiRelatedSample","appendSsaiRoutingParam","trySendBeacon","sendRequestSynchronous","fallbackFunction","requestHeaders","navigator","sendBeacon","blob","Blob","JSON","stringify","adAnalyticsUrl","videoFormatCodecMap","avc","vp9","av1","hevc","MediaSource","isTypeSupported","getOwnPropertyNames","format","some","body","async","xhttp","isLegacyXDomainRequestUsed","XMLHttpRequest","XDomainRequest","onload","parse","responseText","statusText","onerror","openAsyncRequest","isReactNative","open","setRequestHeader","licenseServerUrl","reject","timeout","getInstance","instance","analyticsDebugConfig","console","optionalParams","tabularData","properties","str","join","MESSAGE_NAMESPACE","ANALYTICS_MIN_SEEK_DIFFERENCE_THRESHOLD","anything","isDocumentHidden","BACKGROUND","FOREGROUND","toString","toBoolean","Boolean","valueOf","isObject","isPlainObject","removeTrailingSlash","replace","timeInSeconds","noOp","fromConfig","toConfig","CustomDataUtils","customDataField","numerator","denominator","getURLResourceName","pop","reduce","prev","startsWith","getGlobalNavigatorProduct","isAudioMuted","playerIsMuted","playerVolume","obj","threshold","inViewport","options","rootMargin","observer","IntersectionObserver","entries","handleIntersect","observe","_error","hiddenPropertyName","getDocumentPropertyWithPrefix","visibilityChange","addDocumentEventListener","handleVisibilityChange","isHidden","document","unobserve","disconnect","removeDocumentEventListener","_observer","intersectionRatio","getGlobalWebOSApi","webOSSystem","PalmSystem","deviceInfo","trackedObjects","addGlobalEventListener","removeGlobalEventListener","deviceType","deviceClass","getGlobalLocationHostname","fallbackDomain","origin","oldConfigWithoutSourceRelatedFields","sourceSpecificProperties","customDataFieldsRegex","removeSourceRelatedFields","mergedCollectorConfig","oldCollectorConfig","newCollectorConfig","mergeCollectorConfig","errorMessages","isDomainMissing","fullErrorMessage","prop","pascalCase","charAt","toUpperCase","prefixedProp","hiddenProp","isVideoInFullscreen","fullscreenProp","nodeName","handler","allCookies","cookie","cookieName","substring","attributes","newCookie","globalThis","window","g","getGlobalThis","getGlobalDevicePixelRatio","devicePixelRatio","screen","scale","isFinite","location","getGlobalLocationPathname","userLanguage","product","getGlobalVideojsVersion","videojs","getGlobalTheoPlayerVersion","THEOplayer","parseIntOrUndefined","parseInt","access","isEmpty","trim","suffix","prefix","c","r","random","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","Function"],"sourceRoot":""}